1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // rxk1000_codec.c -- rk1000 ALSA Soc Audio driver
4 //
5 // Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
6
7 #include <linux/delay.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/i2c.h>
10 #include <linux/module.h>
11 #include <sound/core.h>
12 #include <sound/pcm.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc.h>
15 #include <sound/soc-dapm.h>
16 #include "rk1000_codec.h"
17
18 #define FREQ441KHZ (0x11 << 1)
19 /* rk1000 output volume, DAC Digital Gain */
20 /* 0x0000 ~ 0xF42 */
21 #define VOLUME_OUTPUT 0xF42
22 /* 0x0 ~ 0x3f(bit0-bit5) max=0x0(+6DB) min=0x3f(-60DB) Analog Gain */
23 #define VOLUME_CODEC_PA 0x0
24
25 /* rk1000 input volume, rk610 can not adjust the recording volume */
26 #define VOLUME_INPUT 0x07
27
28 #define OUT_CAPLESS (1)
29
30 static const struct reg_default rk1000_codec_reg[] = {
31 { 0x00, 0x05 },
32 { 0x01, 0x04 },
33 { 0x02, 0xfd },
34 { 0x03, 0xf3 },
35 { 0x04, 0x03 },
36 { 0x05, 0x00 },
37 { 0x06, 0x00 },
38 { 0x07, 0x00 },
39 { 0x08, 0x00 },
40 { 0x09, 0x05 },
41 { 0x0a, 0x00 },
42 { 0x0b, 0x00 },
43 { 0x0c, 0x97 },
44 { 0x0d, 0x97 },
45 { 0x0e, 0x97 },
46 { 0x0f, 0x97 },
47 { 0x10, 0x97 },
48 { 0x11, 0x97 },
49 { 0x12, 0xcc },
50 { 0x13, 0x00 },
51 { 0x14, 0x00 },
52 { 0x15, 0xf1 },
53 { 0x16, 0x90 },
54 { 0x17, 0xff },
55 { 0x18, 0xff },
56 { 0x19, 0xff },
57 { 0x1a, 0x9c },
58 { 0x1b, 0x00 },
59 { 0x1c, 0x00 },
60 { 0x1d, 0xff },
61 { 0x1e, 0xff },
62 { 0x1f, 0xff },
63 };
64
65 struct rk1000_codec_priv {
66 struct regmap *regmap;
67 struct regmap *ctlmap;
68 struct snd_soc_component *component;
69 struct delayed_work pa_delayed_work;
70 struct gpio_desc *spk_en_gpio;
71 /*
72 * Some amplifiers enable a longer time.
73 * config after pa_enable_io delay pa_enable_time(ms)
74 * so value range is 0 - 8000.
75 */
76 unsigned int pa_enable_time;
77 };
78
spk_ctrl_fun(struct snd_soc_component * component,int status)79 static void spk_ctrl_fun(struct snd_soc_component *component, int status)
80 {
81 struct rk1000_codec_priv *rk1000_codec;
82
83 rk1000_codec = snd_soc_component_get_drvdata(component);
84
85 if (rk1000_codec->spk_en_gpio)
86 gpiod_set_value(rk1000_codec->spk_en_gpio, status);
87 }
88
rk1000_codec_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)89 static int rk1000_codec_set_bias_level(struct snd_soc_component *component,
90 enum snd_soc_bias_level level)
91 {
92 switch (level) {
93 case SND_SOC_BIAS_ON:
94 break;
95
96 case SND_SOC_BIAS_PREPARE:
97 snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
98 snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
99 snd_soc_component_write(component, ACCELCODEC_R1F, 0x49);
100 break;
101
102 case SND_SOC_BIAS_STANDBY:
103 snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
104 snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
105 snd_soc_component_write(component, ACCELCODEC_R1F, 0x49);
106 break;
107
108 case SND_SOC_BIAS_OFF:
109 spk_ctrl_fun(component, GPIO_LOW);
110 snd_soc_component_write(component, ACCELCODEC_R1D, 0xFF);
111 snd_soc_component_write(component, ACCELCODEC_R1E, 0xFF);
112 snd_soc_component_write(component, ACCELCODEC_R1F, 0xFF);
113 break;
114 }
115 return 0;
116 }
117
rk1000_codec_set_dai_fmt(struct snd_soc_dai * codec_dai,unsigned int fmt)118 static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
119 unsigned int fmt)
120 {
121 struct snd_soc_component *component = codec_dai->component;
122 struct rk1000_codec_priv *rk1000_codec;
123 u16 iface = 0;
124
125 rk1000_codec = snd_soc_component_get_drvdata(component);
126 /* setup Vmid and Vref, other module power down */
127 snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
128 snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
129 /* set master/slave audio interface */
130 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
131 case SND_SOC_DAIFMT_CBM_CFM:
132 iface = 0x0040;
133 break;
134
135 case SND_SOC_DAIFMT_CBS_CFS:
136 iface = 0x0000;
137 break;
138
139 default:
140 return -EINVAL;
141 }
142 /* interface format */
143 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
144 case SND_SOC_DAIFMT_I2S:
145 iface |= 0x0002;
146 break;
147
148 case SND_SOC_DAIFMT_RIGHT_J:
149 break;
150
151 case SND_SOC_DAIFMT_LEFT_J:
152 iface |= 0x0001;
153 break;
154
155 case SND_SOC_DAIFMT_DSP_A:
156 iface |= 0x0003;
157 break;
158
159 case SND_SOC_DAIFMT_DSP_B:
160 iface |= 0x0013;
161 break;
162
163 default:
164 return -EINVAL;
165 }
166
167 /* clock inversion */
168 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
169 case SND_SOC_DAIFMT_NB_NF:
170 break;
171
172 case SND_SOC_DAIFMT_IB_IF:
173 iface |= 0x0090;
174 break;
175
176 case SND_SOC_DAIFMT_IB_NF:
177 iface |= 0x0080;
178 break;
179
180 case SND_SOC_DAIFMT_NB_IF:
181 iface |= 0x0010;
182 break;
183
184 default:
185 return -EINVAL;
186 }
187
188 snd_soc_component_write(component, ACCELCODEC_R09, iface);
189
190 return 0;
191 }
192
rk1000_codec_pcm_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)193 static int rk1000_codec_pcm_hw_params(struct snd_pcm_substream *substream,
194 struct snd_pcm_hw_params *params,
195 struct snd_soc_dai *dai)
196 {
197 u32 iface;
198 struct snd_soc_pcm_runtime *rtd = substream->private_data;
199 struct snd_soc_component *component = dai->component;
200 unsigned int dai_fmt;
201
202 dai_fmt = rtd->card->dai_link[0].dai_fmt;
203 iface = snd_soc_component_read(component, ACCELCODEC_R09) & 0x1f3;
204 snd_soc_component_write(component, ACCELCODEC_R0C, 0x17);
205 snd_soc_component_write(component, ACCELCODEC_R04,
206 ASC_INT_MUTE_L | ASC_INT_MUTE_R |
207 ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
208 snd_soc_component_write(component, ACCELCODEC_R0B,
209 ASC_DEC_DISABLE | ASC_INT_DISABLE);
210
211 if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
212 iface |= ASC_INVERT_BCLK;
213 snd_soc_component_write(component, ACCELCODEC_R09, iface);
214 snd_soc_component_write(component, ACCELCODEC_R0A, 0xa0);
215 snd_soc_component_write(component, ACCELCODEC_R0B, ASC_DEC_ENABLE | ASC_INT_ENABLE);
216
217 return 0;
218 }
219
rk1000_codec_mute(struct snd_soc_dai * dai,int mute,int stream)220 static int rk1000_codec_mute(struct snd_soc_dai *dai, int mute, int stream)
221 {
222 struct snd_soc_component *component = dai->component;
223 struct rk1000_codec_priv *rk1000_codec;
224
225 rk1000_codec = snd_soc_component_get_drvdata(component);
226 if (mute) {
227 /* AOL */
228 snd_soc_component_write(component, ACCELCODEC_R17, 0xFF);
229 /* AOR */
230 snd_soc_component_write(component, ACCELCODEC_R18, 0xFF);
231 /* AOM */
232 snd_soc_component_write(component, ACCELCODEC_R19, 0xFF);
233 /* soft mute */
234 snd_soc_component_write(component, ACCELCODEC_R04,
235 ASC_INT_MUTE_L | ASC_INT_MUTE_R |
236 ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
237 } else {
238 /* setup Vmid and Vref, other module power down */
239 snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a);
240 snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
241 /* AOL */
242 snd_soc_component_write(component, ACCELCODEC_R17,
243 VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE |
244 ASC_CROSSZERO_EN);
245 /* AOR */
246 snd_soc_component_write(component, ACCELCODEC_R18,
247 VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE |
248 ASC_CROSSZERO_EN);
249 snd_soc_component_write(component, ACCELCODEC_R04,
250 ASC_INT_ACTIVE_L | ASC_INT_ACTIVE_R |
251 ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
252 /* AOM */
253 snd_soc_component_write(component, ACCELCODEC_R19, 0x7F);
254 #if OUT_CAPLESS
255 snd_soc_component_write(component, ACCELCODEC_R1F,
256 0x09 | ASC_PDMIXM_ENABLE);
257 #else
258 snd_soc_component_write(component, ACCELCODEC_R1F,
259 0x09 | ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE);
260 #endif
261 }
262
263 return 0;
264 }
265
pa_delayedwork(struct work_struct * work)266 static void pa_delayedwork(struct work_struct *work)
267 {
268 struct rk1000_codec_priv *priv = container_of(work,
269 struct rk1000_codec_priv,
270 pa_delayed_work.work);
271 struct snd_soc_component *component = priv->component;
272
273 spk_ctrl_fun(component, GPIO_HIGH);
274 }
275
276 static struct snd_soc_dai_ops rk1000_codec_ops = {
277 .hw_params = rk1000_codec_pcm_hw_params,
278 .set_fmt = rk1000_codec_set_dai_fmt,
279 .mute_stream = rk1000_codec_mute,
280 .no_capture_mute = 1,
281 };
282
283 #define RK1000_CODEC_RATES SNDRV_PCM_RATE_8000_192000
284 #define RK1000_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
285 SNDRV_PCM_FMTBIT_S20_3LE | \
286 SNDRV_PCM_FMTBIT_S24_LE)
287
288 static struct snd_soc_dai_driver rk1000_codec_dai[] = {
289 {
290 .name = "rk1000_codec",
291 .playback = {
292 .stream_name = "Playback",
293 .channels_min = 2,
294 .channels_max = 8,
295 .rates = RK1000_CODEC_RATES,
296 .formats = RK1000_CODEC_FORMATS,
297 },
298 .capture = {
299 .stream_name = "Capture",
300 .channels_min = 2,
301 .channels_max = 2,
302 .rates = RK1000_CODEC_RATES,
303 .formats = RK1000_CODEC_FORMATS,
304 },
305 .ops = &rk1000_codec_ops,
306 .symmetric_rates = 1,
307 }
308 };
309
rk1000_codec_reg_init(struct snd_soc_component * component)310 static void rk1000_codec_reg_init(struct snd_soc_component *component)
311 {
312 struct rk1000_codec_priv *rk1000_codec;
313 unsigned int digital_gain;
314 unsigned int mic_vol;
315 int ret;
316
317 mic_vol = VOLUME_INPUT;
318 rk1000_codec = snd_soc_component_get_drvdata(component);
319 ret = snd_soc_component_write(component, ACCELCODEC_R1D, 0x30);
320 snd_soc_component_write(component, ACCELCODEC_R1E, 0x40);
321 /*Route R-LPF->R-Mixer, L-LPF->L-Mixer*/
322 snd_soc_component_write(component, ACCELCODEC_R15, 0xC1);
323 /*With Cap Output, VMID ramp up slow*/
324 snd_soc_component_write(component, ACCELCODEC_R1A, 0x14);
325 mdelay(10);
326 snd_soc_component_write(component, ACCELCODEC_R0C, 0x10 | ASC_INPUT_VOL_0DB);
327 snd_soc_component_write(component, ACCELCODEC_R0D, 0x10 | ASC_INPUT_VOL_0DB);
328 if (mic_vol > 0x07) {
329 /*Select MIC input*/
330 snd_soc_component_write(component, ACCELCODEC_R12,
331 0x4c | ASC_MIC_INPUT | ASC_MIC_BOOST_20DB);
332 mic_vol -= 0x07;
333 } else {
334 /*Select MIC input*/
335 snd_soc_component_write(component, ACCELCODEC_R12, 0x4c | ASC_MIC_INPUT);
336 }
337 /*use default value*/
338 snd_soc_component_write(component, ACCELCODEC_R1C, ASC_DEM_ENABLE);
339 snd_soc_component_write(component, ACCELCODEC_R0E, 0x10 | mic_vol);
340 /* disable route PGA->R/L Mixer, PGA gain 0db. */
341 snd_soc_component_write(component, ACCELCODEC_R13, 0x05 | 0 << 3);
342 snd_soc_component_write(component, ACCELCODEC_R14, 0x05 | 0 << 3);
343 /*2soft mute*/
344 snd_soc_component_write(component, ACCELCODEC_R04,
345 ASC_INT_MUTE_L | ASC_INT_MUTE_R |
346 ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
347 /*2set default SR and clk*/
348 snd_soc_component_write(component, ACCELCODEC_R0A, FREQ441KHZ | ASC_NORMAL_MODE |
349 (0x10 << 1) | ASC_CLKNODIV | ASC_CLK_ENABLE);
350 /*2Config audio interface*/
351 snd_soc_component_write(component, ACCELCODEC_R09, ASC_I2S_MODE |
352 ASC_16BIT_MODE | ASC_NORMAL_LRCLK |
353 ASC_LRSWAP_DISABLE | ASC_NORMAL_BCLK);
354 snd_soc_component_write(component, ACCELCODEC_R00, ASC_HPF_ENABLE |
355 ASC_DSM_MODE_ENABLE | ASC_SCRAMBLE_ENABLE |
356 ASC_DITHER_ENABLE | ASC_BCLKDIV_4);
357 /*2volume,input,output*/
358 digital_gain = VOLUME_OUTPUT;
359 if (snd_soc_component_read(component, ACCELCODEC_R05) != 0x0f) {
360 snd_soc_component_write(component, ACCELCODEC_R05,
361 (digital_gain >> 8) & 0xFF);
362 snd_soc_component_write(component, ACCELCODEC_R06, digital_gain & 0xFF);
363 }
364
365 if (snd_soc_component_read(component, ACCELCODEC_R07) != 0x0f) {
366 snd_soc_component_write(component, ACCELCODEC_R07,
367 (digital_gain >> 8) & 0xFF);
368 snd_soc_component_write(component, ACCELCODEC_R08, digital_gain & 0xFF);
369 }
370
371 snd_soc_component_write(component, ACCELCODEC_R0B,
372 ASC_DEC_ENABLE | ASC_INT_ENABLE);
373
374 #if OUT_CAPLESS
375 snd_soc_component_write(component, ACCELCODEC_R1F,
376 0x09 | ASC_PDMIXM_ENABLE);
377 #else
378 snd_soc_component_write(component, ACCELCODEC_R1F, 0x09 |
379 ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE);
380 #endif
381
382 snd_soc_component_write(component, ACCELCODEC_R17, VOLUME_CODEC_PA |
383 ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
384 snd_soc_component_write(component, ACCELCODEC_R18, VOLUME_CODEC_PA |
385 ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
386 snd_soc_component_write(component, ACCELCODEC_R04, ASC_INT_ACTIVE_L |
387 ASC_INT_ACTIVE_R | ASC_SIDETONE_L_OFF |
388 ASC_SIDETONE_R_OFF);
389 snd_soc_component_write(component, ACCELCODEC_R19, 0x7F);
390 }
391
rk1000_codec_suspend(struct snd_soc_component * component)392 static int rk1000_codec_suspend(struct snd_soc_component *component)
393 {
394 spk_ctrl_fun(component, GPIO_LOW);
395 rk1000_codec_set_bias_level(component, SND_SOC_BIAS_OFF);
396
397 return 0;
398 }
399
rk1000_codec_resume(struct snd_soc_component * component)400 static int rk1000_codec_resume(struct snd_soc_component *component)
401 {
402 rk1000_codec_set_bias_level(component, SND_SOC_BIAS_PREPARE);
403 spk_ctrl_fun(component, GPIO_HIGH);
404
405 return 0;
406 }
407
rk1000_codec_probe(struct snd_soc_component * component)408 static int rk1000_codec_probe(struct snd_soc_component *component)
409 {
410 struct rk1000_codec_priv *rk1000_codec;
411
412 rk1000_codec = snd_soc_component_get_drvdata(component);
413 rk1000_codec->component = component;
414
415 INIT_DELAYED_WORK(&rk1000_codec->pa_delayed_work,
416 pa_delayedwork);
417
418 rk1000_codec_set_bias_level(component, SND_SOC_BIAS_PREPARE);
419 schedule_delayed_work(&rk1000_codec->pa_delayed_work,
420 msecs_to_jiffies(rk1000_codec->pa_enable_time));
421 rk1000_codec_reg_init(component);
422
423 return 0;
424 }
425
rk1000_codec_remove(struct snd_soc_component * component)426 static void rk1000_codec_remove(struct snd_soc_component *component)
427 {
428 rk1000_codec_set_bias_level(component, SND_SOC_BIAS_OFF);
429 }
430
431 static const struct snd_soc_component_driver soc_codec_dev_rk1000_codec = {
432 .probe = rk1000_codec_probe,
433 .remove = rk1000_codec_remove,
434 .suspend = rk1000_codec_suspend,
435 .resume = rk1000_codec_resume,
436 .set_bias_level = rk1000_codec_set_bias_level,
437 };
438
rk1000_reg_write(void * context,unsigned int reg,unsigned int value)439 static int rk1000_reg_write(void *context, unsigned int reg,
440 unsigned int value)
441 {
442 struct i2c_client *i2c = context;
443 struct i2c_msg msg;
444 u8 buf;
445 int ret;
446
447 buf = value;
448 msg.addr = i2c->addr | reg;
449 msg.flags = i2c->flags & I2C_M_TEN;
450 msg.len = 1;
451 msg.buf = &buf;
452
453 ret = i2c_transfer(i2c->adapter, &msg, 1);
454
455 return (ret == 1) ? 0 : ret;
456 }
457
rk1000_reg_read(void * context,unsigned int reg,unsigned int * value)458 static int rk1000_reg_read(void *context, unsigned int reg,
459 unsigned int *value)
460 {
461 struct i2c_client *i2c = context;
462 struct i2c_msg msg;
463 u8 buf;
464 int ret;
465
466 msg.addr = i2c->addr | reg;
467 msg.flags = I2C_M_RD;
468 msg.len = 1;
469 msg.buf = &buf;
470
471 ret = i2c_transfer(i2c->adapter, &msg, 1);
472 if (ret != 1)
473 return ret;
474
475 *value = buf;
476
477 return 0;
478 }
479
480 static const struct regmap_config rk1000_codec_regmap = {
481 .reg_bits = 8,
482 .val_bits = 8,
483 .reg_write = rk1000_reg_write,
484 .reg_read = rk1000_reg_read,
485 .max_register = ACCELCODEC_R1F,
486 .cache_type = REGCACHE_FLAT,
487 .reg_defaults = rk1000_codec_reg,
488 .num_reg_defaults = ARRAY_SIZE(rk1000_codec_reg),
489 };
490
491 static const struct regmap_config rk1000_ctl_regmap = {
492 .reg_bits = 8,
493 .val_bits = 8,
494 .max_register = CODEC_CON,
495 .cache_type = REGCACHE_FLAT,
496 };
497
rk1000_codec_i2c_probe(struct i2c_client * i2c,const struct i2c_device_id * id)498 static int rk1000_codec_i2c_probe(struct i2c_client *i2c,
499 const struct i2c_device_id *id)
500 {
501 struct rk1000_codec_priv *rk1000;
502 struct device_node *np = i2c->dev.of_node;
503 struct device_node *ctl;
504 struct i2c_client *ctl_client;
505
506 rk1000 = devm_kzalloc(&i2c->dev, sizeof(*rk1000), GFP_KERNEL);
507 if (!rk1000)
508 return -ENOMEM;
509
510 i2c_set_clientdata(i2c, rk1000);
511
512 of_property_read_u32(np, "rockchip,pa-en-time-ms",
513 &rk1000->pa_enable_time);
514
515 rk1000->spk_en_gpio = devm_gpiod_get_optional(&i2c->dev, "rockchip,spk-en",
516 GPIOD_OUT_LOW);
517 if (IS_ERR(rk1000->spk_en_gpio))
518 return PTR_ERR(rk1000->spk_en_gpio);
519
520 ctl = of_parse_phandle(np, "rockchip,ctl", 0);
521 if (!ctl)
522 return -EINVAL;
523
524 ctl_client = of_find_i2c_device_by_node(ctl);
525 if (!ctl_client) {
526 dev_err(&i2c->dev, "can't find control client\n");
527 return -EPROBE_DEFER;
528 }
529
530 rk1000->regmap = devm_regmap_init(&i2c->dev, NULL,
531 i2c, &rk1000_codec_regmap);
532 if (IS_ERR(rk1000->regmap))
533 return PTR_ERR(rk1000->regmap);
534
535 rk1000->ctlmap = devm_regmap_init_i2c(ctl_client,
536 &rk1000_ctl_regmap);
537 if (IS_ERR(rk1000->ctlmap))
538 return PTR_ERR(rk1000->ctlmap);
539
540 regmap_write(rk1000->ctlmap, CODEC_CON, CODEC_ON);
541
542 return devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_rk1000_codec,
543 rk1000_codec_dai,
544 ARRAY_SIZE(rk1000_codec_dai));
545 }
546
rk1000_codec_i2c_remove(struct i2c_client * i2c)547 static int rk1000_codec_i2c_remove(struct i2c_client *i2c)
548 {
549 struct rk1000_codec_priv *rk1000 = i2c_get_clientdata(i2c);
550
551 regmap_write(rk1000->ctlmap, CODEC_CON, CODEC_OFF);
552
553 return 0;
554 }
555
556 static const struct i2c_device_id rk1000_codec_i2c_id[] = {
557 { "rk1000_codec", 0 },
558 { }
559 };
560 MODULE_DEVICE_TABLE(i2c, rk1000_codec_i2c_id);
561
562 static const struct of_device_id rk1000_codec_of_match[] = {
563 { .compatible = "rockchip,rk1000-codec", },
564 {},
565 };
566
567 static struct i2c_driver rk1000_codec_i2c_driver = {
568 .driver = {
569 .name = "rk1000_codec",
570 .of_match_table = of_match_ptr(rk1000_codec_of_match),
571 },
572 .probe = rk1000_codec_i2c_probe,
573 .remove = rk1000_codec_i2c_remove,
574 .id_table = rk1000_codec_i2c_id,
575 };
576 module_i2c_driver(rk1000_codec_i2c_driver);
577
578 MODULE_DESCRIPTION("Rockchip RK1000 CODEC driver");
579 MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
580 MODULE_LICENSE("GPL v2");
581