11
11
#include <linux/i2c.h>
12
12
#include <linux/of_device.h>
13
13
#include <linux/module.h>
14
+ #include <linux/regmap.h>
14
15
15
16
#define CH_MAX 4
16
17
#define RATIO_REG_SIZE 4
74
75
#define REF_CLK 1
75
76
#define CLK_MAX 2
76
77
78
+ static bool cs2000_readable_reg (struct device * dev , unsigned int reg )
79
+ {
80
+ return reg > 0 ;
81
+ }
82
+
83
+ static bool cs2000_writeable_reg (struct device * dev , unsigned int reg )
84
+ {
85
+ return reg != DEVICE_ID ;
86
+ }
87
+
88
+ static bool cs2000_volatile_reg (struct device * dev , unsigned int reg )
89
+ {
90
+ return reg == DEVICE_CTRL ;
91
+ }
92
+
93
+ static const struct regmap_config cs2000_regmap_config = {
94
+ .reg_bits = 8 ,
95
+ .val_bits = 8 ,
96
+ .max_register = FUNC_CFG2 ,
97
+ .readable_reg = cs2000_readable_reg ,
98
+ .writeable_reg = cs2000_writeable_reg ,
99
+ .volatile_reg = cs2000_volatile_reg ,
100
+ };
101
+
77
102
struct cs2000_priv {
78
103
struct clk_hw hw ;
79
104
struct i2c_client * client ;
80
105
struct clk * clk_in ;
81
106
struct clk * ref_clk ;
107
+ struct regmap * regmap ;
82
108
83
109
bool dynamic_mode ;
84
110
bool lf_ratio ;
@@ -101,41 +127,22 @@ static const struct i2c_device_id cs2000_id[] = {
101
127
};
102
128
MODULE_DEVICE_TABLE (i2c , cs2000_id );
103
129
104
- #define cs2000_read (priv , addr ) \
105
- i2c_smbus_read_byte_data(priv_to_client(priv), addr)
106
- #define cs2000_write (priv , addr , val ) \
107
- i2c_smbus_write_byte_data(priv_to_client(priv), addr, val)
108
-
109
- static int cs2000_bset (struct cs2000_priv * priv , u8 addr , u8 mask , u8 val )
110
- {
111
- s32 data ;
112
-
113
- data = cs2000_read (priv , addr );
114
- if (data < 0 )
115
- return data ;
116
-
117
- data &= ~mask ;
118
- data |= (val & mask );
119
-
120
- return cs2000_write (priv , addr , data );
121
- }
122
-
123
130
static int cs2000_enable_dev_config (struct cs2000_priv * priv , bool enable )
124
131
{
125
132
int ret ;
126
133
127
- ret = cs2000_bset (priv , DEVICE_CFG1 , ENDEV1 ,
128
- enable ? ENDEV1 : 0 );
134
+ ret = regmap_update_bits (priv -> regmap , DEVICE_CFG1 , ENDEV1 ,
135
+ enable ? ENDEV1 : 0 );
129
136
if (ret < 0 )
130
137
return ret ;
131
138
132
- ret = cs2000_bset (priv , GLOBAL_CFG , ENDEV2 ,
133
- enable ? ENDEV2 : 0 );
139
+ ret = regmap_update_bits (priv -> regmap , GLOBAL_CFG , ENDEV2 ,
140
+ enable ? ENDEV2 : 0 );
134
141
if (ret < 0 )
135
142
return ret ;
136
143
137
- ret = cs2000_bset (priv , FUNC_CFG1 , CLKSKIPEN ,
138
- (enable && priv -> clk_skip ) ? CLKSKIPEN : 0 );
144
+ ret = regmap_update_bits (priv -> regmap , FUNC_CFG1 , CLKSKIPEN ,
145
+ (enable && priv -> clk_skip ) ? CLKSKIPEN : 0 );
139
146
if (ret < 0 )
140
147
return ret ;
141
148
@@ -156,21 +163,21 @@ static int cs2000_ref_clk_bound_rate(struct cs2000_priv *priv,
156
163
else
157
164
return - EINVAL ;
158
165
159
- return cs2000_bset (priv , FUNC_CFG1 ,
160
- REFCLKDIV_MASK ,
161
- REFCLKDIV (val ));
166
+ return regmap_update_bits (priv -> regmap , FUNC_CFG1 ,
167
+ REFCLKDIV_MASK ,
168
+ REFCLKDIV (val ));
162
169
}
163
170
164
171
static int cs2000_wait_pll_lock (struct cs2000_priv * priv )
165
172
{
166
173
struct device * dev = priv_to_dev (priv );
167
- s32 val ;
168
- unsigned int i ;
174
+ unsigned int i , val ;
175
+ int ret ;
169
176
170
177
for (i = 0 ; i < 256 ; i ++ ) {
171
- val = cs2000_read (priv , DEVICE_CTRL );
172
- if (val < 0 )
173
- return val ;
178
+ ret = regmap_read (priv -> regmap , DEVICE_CTRL , & val );
179
+ if (ret < 0 )
180
+ return ret ;
174
181
if (!(val & PLL_UNLOCK ))
175
182
return 0 ;
176
183
udelay (1 );
@@ -184,10 +191,10 @@ static int cs2000_wait_pll_lock(struct cs2000_priv *priv)
184
191
static int cs2000_clk_out_enable (struct cs2000_priv * priv , bool enable )
185
192
{
186
193
/* enable both AUX_OUT, CLK_OUT */
187
- return cs2000_bset (priv , DEVICE_CTRL ,
188
- (AUXOUTDIS | CLKOUTDIS ),
189
- enable ? 0 :
190
- (AUXOUTDIS | CLKOUTDIS ));
194
+ return regmap_update_bits (priv -> regmap , DEVICE_CTRL ,
195
+ (AUXOUTDIS | CLKOUTDIS ),
196
+ enable ? 0 :
197
+ (AUXOUTDIS | CLKOUTDIS ));
191
198
}
192
199
193
200
static u32 cs2000_rate_to_ratio (u32 rate_in , u32 rate_out , bool lf_ratio )
@@ -235,7 +242,7 @@ static int cs2000_ratio_set(struct cs2000_priv *priv,
235
242
236
243
val = cs2000_rate_to_ratio (rate_in , rate_out , priv -> lf_ratio );
237
244
for (i = 0 ; i < RATIO_REG_SIZE ; i ++ ) {
238
- ret = cs2000_write (priv ,
245
+ ret = regmap_write (priv -> regmap ,
239
246
Ratio_Add (ch , i ),
240
247
Ratio_Val (val , i ));
241
248
if (ret < 0 )
@@ -247,14 +254,14 @@ static int cs2000_ratio_set(struct cs2000_priv *priv,
247
254
248
255
static u32 cs2000_ratio_get (struct cs2000_priv * priv , int ch )
249
256
{
250
- s32 tmp ;
257
+ unsigned int tmp , i ;
251
258
u32 val ;
252
- unsigned int i ;
259
+ int ret ;
253
260
254
261
val = 0 ;
255
262
for (i = 0 ; i < RATIO_REG_SIZE ; i ++ ) {
256
- tmp = cs2000_read (priv , Ratio_Add (ch , i ));
257
- if (tmp < 0 )
263
+ ret = regmap_read (priv -> regmap , Ratio_Add (ch , i ), & tmp );
264
+ if (ret < 0 )
258
265
return 0 ;
259
266
260
267
val |= Val_Ratio (tmp , i );
@@ -271,15 +278,15 @@ static int cs2000_ratio_select(struct cs2000_priv *priv, int ch)
271
278
if (CH_SIZE_ERR (ch ))
272
279
return - EINVAL ;
273
280
274
- ret = cs2000_bset (priv , DEVICE_CFG1 , RSEL_MASK , RSEL (ch ));
281
+ ret = regmap_update_bits (priv -> regmap , DEVICE_CFG1 , RSEL_MASK , RSEL (ch ));
275
282
if (ret < 0 )
276
283
return ret ;
277
284
278
285
fracnsrc = priv -> dynamic_mode ? FRACNSRC_DYNAMIC : FRACNSRC_STATIC ;
279
286
280
- ret = cs2000_bset (priv , DEVICE_CFG2 ,
281
- AUTORMOD | LOCKCLK_MASK | FRACNSRC_MASK ,
282
- LOCKCLK (ch ) | fracnsrc );
287
+ ret = regmap_update_bits (priv -> regmap , DEVICE_CFG2 ,
288
+ AUTORMOD | LOCKCLK_MASK | FRACNSRC_MASK ,
289
+ LOCKCLK (ch ) | fracnsrc );
283
290
if (ret < 0 )
284
291
return ret ;
285
292
@@ -326,8 +333,8 @@ static int cs2000_select_ratio_mode(struct cs2000_priv *priv,
326
333
*/
327
334
priv -> lf_ratio = priv -> dynamic_mode && ((rate / parent_rate ) > 4096 );
328
335
329
- return cs2000_bset (priv , FUNC_CFG2 , LFRATIO_MASK ,
330
- priv -> lf_ratio ? LFRATIO_20_12 : LFRATIO_12_20 );
336
+ return regmap_update_bits (priv -> regmap , FUNC_CFG2 , LFRATIO_MASK ,
337
+ priv -> lf_ratio ? LFRATIO_20_12 : LFRATIO_12_20 );
331
338
}
332
339
333
340
static int __cs2000_set_rate (struct cs2000_priv * priv , int ch ,
@@ -336,7 +343,7 @@ static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
336
343
{
337
344
int ret ;
338
345
339
- ret = cs2000_bset (priv , GLOBAL_CFG , FREEZE , FREEZE );
346
+ ret = regmap_update_bits (priv -> regmap , GLOBAL_CFG , FREEZE , FREEZE );
340
347
if (ret < 0 )
341
348
return ret ;
342
349
@@ -352,7 +359,7 @@ static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
352
359
if (ret < 0 )
353
360
return ret ;
354
361
355
- ret = cs2000_bset (priv , GLOBAL_CFG , FREEZE , 0 );
362
+ ret = regmap_update_bits (priv -> regmap , GLOBAL_CFG , FREEZE , 0 );
356
363
if (ret < 0 )
357
364
return ret ;
358
365
@@ -469,8 +476,8 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
469
476
priv -> dynamic_mode ? "dynamic" : "static" );
470
477
471
478
of_property_read_u32 (np , "cirrus,aux-output-source" , & aux_out );
472
- ret = cs2000_bset (priv , DEVICE_CFG1 ,
473
- AUXOUTSRC_MASK , AUXOUTSRC (aux_out ));
479
+ ret = regmap_update_bits (priv -> regmap , DEVICE_CFG1 ,
480
+ AUXOUTSRC_MASK , AUXOUTSRC (aux_out ));
474
481
if (ret < 0 )
475
482
return ret ;
476
483
@@ -522,12 +529,13 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
522
529
static int cs2000_version_print (struct cs2000_priv * priv )
523
530
{
524
531
struct device * dev = priv_to_dev (priv );
525
- s32 val ;
526
532
const char * revision ;
533
+ unsigned int val ;
534
+ int ret ;
527
535
528
- val = cs2000_read (priv , DEVICE_ID );
529
- if (val < 0 )
530
- return val ;
536
+ ret = regmap_read (priv -> regmap , DEVICE_ID , & val );
537
+ if (ret < 0 )
538
+ return ret ;
531
539
532
540
/* CS2000 should be 0x0 */
533
541
if (val >> 3 )
@@ -576,6 +584,10 @@ static int cs2000_probe(struct i2c_client *client,
576
584
priv -> client = client ;
577
585
i2c_set_clientdata (client , priv );
578
586
587
+ priv -> regmap = devm_regmap_init_i2c (client , & cs2000_regmap_config );
588
+ if (IS_ERR (priv -> regmap ))
589
+ return PTR_ERR (priv -> regmap );
590
+
579
591
ret = cs2000_clk_get (priv );
580
592
if (ret < 0 )
581
593
return ret ;
0 commit comments