xref: /linux/sound/soc/codecs/cs42l51.c (revision d39d0ed196aa1685bb24771e92f78633c66ac9cb)
1 /*
2  * cs42l51.c
3  *
4  * ASoC Driver for Cirrus Logic CS42L51 codecs
5  *
6  * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
7  *
8  * Based on cs4270.c - Copyright (c) Freescale Semiconductor
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * For now:
20  *  - Only I2C is support. Not SPI
21  *  - master mode *NOT* supported
22  */
23 
24 #include <linux/module.h>
25 #include <linux/platform_device.h>
26 #include <linux/slab.h>
27 #include <sound/core.h>
28 #include <sound/soc.h>
29 #include <sound/soc-dapm.h>
30 #include <sound/tlv.h>
31 #include <sound/initval.h>
32 #include <sound/pcm_params.h>
33 #include <sound/pcm.h>
34 #include <linux/i2c.h>
35 
36 #include "cs42l51.h"
37 
38 enum master_slave_mode {
39 	MODE_SLAVE,
40 	MODE_SLAVE_AUTO,
41 	MODE_MASTER,
42 };
43 
44 struct cs42l51_private {
45 	unsigned int mclk;
46 	unsigned int audio_mode;	/* The mode (I2S or left-justified) */
47 	enum master_slave_mode func;
48 	struct snd_soc_codec codec;
49 	u8 reg_cache[CS42L51_NUMREGS];
50 };
51 
52 static struct snd_soc_codec *cs42l51_codec;
53 
54 #define CS42L51_FORMATS ( \
55 		SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S16_BE  | \
56 		SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
57 		SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
58 		SNDRV_PCM_FMTBIT_S24_LE  | SNDRV_PCM_FMTBIT_S24_BE)
59 
60 static int cs42l51_fill_cache(struct snd_soc_codec *codec)
61 {
62 	u8 *cache = codec->reg_cache + 1;
63 	struct i2c_client *i2c_client = codec->control_data;
64 	s32 length;
65 
66 	length = i2c_smbus_read_i2c_block_data(i2c_client,
67 			CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
68 	if (length != CS42L51_NUMREGS) {
69 		dev_err(&i2c_client->dev,
70 				"I2C read failure, addr=0x%x (ret=%d vs %d)\n",
71 				i2c_client->addr, length, CS42L51_NUMREGS);
72 		return -EIO;
73 	}
74 
75 	return 0;
76 }
77 
78 static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
79 	const struct i2c_device_id *id)
80 {
81 	struct snd_soc_codec *codec;
82 	struct cs42l51_private *cs42l51;
83 	int ret = 0;
84 	int reg;
85 
86 	if (cs42l51_codec)
87 		return -EBUSY;
88 
89 	/* Verify that we have a CS42L51 */
90 	ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
91 	if (ret < 0) {
92 		dev_err(&i2c_client->dev, "failed to read I2C\n");
93 		goto error;
94 	}
95 
96 	if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
97 	    (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
98 		dev_err(&i2c_client->dev, "Invalid chip id\n");
99 		ret = -ENODEV;
100 		goto error;
101 	}
102 
103 	dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
104 				ret & 7);
105 
106 	cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
107 	if (!cs42l51) {
108 		dev_err(&i2c_client->dev, "could not allocate codec\n");
109 		return -ENOMEM;
110 	}
111 	codec = &cs42l51->codec;
112 
113 	mutex_init(&codec->mutex);
114 	INIT_LIST_HEAD(&codec->dapm_widgets);
115 	INIT_LIST_HEAD(&codec->dapm_paths);
116 
117 	codec->dev = &i2c_client->dev;
118 	codec->name = "CS42L51";
119 	codec->owner = THIS_MODULE;
120 	codec->dai = &cs42l51_dai;
121 	codec->num_dai = 1;
122 	snd_soc_codec_set_drvdata(codec, cs42l51);
123 
124 	codec->control_data = i2c_client;
125 	codec->reg_cache = cs42l51->reg_cache;
126 	codec->reg_cache_size = CS42L51_NUMREGS;
127 	i2c_set_clientdata(i2c_client, codec);
128 
129 	ret = cs42l51_fill_cache(codec);
130 	if (ret < 0) {
131 		dev_err(&i2c_client->dev, "failed to fill register cache\n");
132 		goto error_alloc;
133 	}
134 
135 	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
136 	if (ret < 0) {
137 		dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
138 		goto error_alloc;
139 	}
140 
141 	/*
142 	 * DAC configuration
143 	 * - Use signal processor
144 	 * - auto mute
145 	 * - vol changes immediate
146 	 * - no de-emphasize
147 	 */
148 	reg = CS42L51_DAC_CTL_DATA_SEL(1)
149 		| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
150 	ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
151 	if (ret < 0)
152 		goto error_alloc;
153 
154 	cs42l51_dai.dev = codec->dev;
155 	cs42l51_codec = codec;
156 
157 	ret = snd_soc_register_codec(codec);
158 	if (ret != 0) {
159 		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
160 		goto error_alloc;
161 	}
162 
163 	ret = snd_soc_register_dai(&cs42l51_dai);
164 	if (ret < 0) {
165 		dev_err(&i2c_client->dev, "failed to register DAIe\n");
166 		goto error_reg;
167 	}
168 
169 	return 0;
170 
171 error_reg:
172 	snd_soc_unregister_codec(codec);
173 error_alloc:
174 	kfree(cs42l51);
175 error:
176 	return ret;
177 }
178 
179 static int cs42l51_i2c_remove(struct i2c_client *client)
180 {
181 	struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
182 	snd_soc_unregister_dai(&cs42l51_dai);
183 	snd_soc_unregister_codec(cs42l51_codec);
184 	cs42l51_codec = NULL;
185 	kfree(cs42l51);
186 	return 0;
187 }
188 
189 
190 static const struct i2c_device_id cs42l51_id[] = {
191 	{"cs42l51", 0},
192 	{}
193 };
194 MODULE_DEVICE_TABLE(i2c, cs42l51_id);
195 
196 static struct i2c_driver cs42l51_i2c_driver = {
197 	.driver = {
198 		.name = "CS42L51 I2C",
199 		.owner = THIS_MODULE,
200 	},
201 	.id_table = cs42l51_id,
202 	.probe = cs42l51_i2c_probe,
203 	.remove = cs42l51_i2c_remove,
204 };
205 
206 static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
207 			struct snd_ctl_elem_value *ucontrol)
208 {
209 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
210 	unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
211 
212 	switch (value) {
213 	default:
214 	case 0:
215 		ucontrol->value.integer.value[0] = 0;
216 		break;
217 	/* same value : (L+R)/2 and (R+L)/2 */
218 	case 1:
219 	case 2:
220 		ucontrol->value.integer.value[0] = 1;
221 		break;
222 	case 3:
223 		ucontrol->value.integer.value[0] = 2;
224 		break;
225 	}
226 
227 	return 0;
228 }
229 
230 #define CHAN_MIX_NORMAL	0x00
231 #define CHAN_MIX_BOTH	0x55
232 #define CHAN_MIX_SWAP	0xFF
233 
234 static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
235 			struct snd_ctl_elem_value *ucontrol)
236 {
237 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
238 	unsigned char val;
239 
240 	switch (ucontrol->value.integer.value[0]) {
241 	default:
242 	case 0:
243 		val = CHAN_MIX_NORMAL;
244 		break;
245 	case 1:
246 		val = CHAN_MIX_BOTH;
247 		break;
248 	case 2:
249 		val = CHAN_MIX_SWAP;
250 		break;
251 	}
252 
253 	snd_soc_write(codec, CS42L51_PCM_MIXER, val);
254 
255 	return 1;
256 }
257 
258 static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);
259 static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
260 /* This is a lie. after -102 db, it stays at -102 */
261 /* maybe a range would be better */
262 static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0);
263 
264 static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
265 static const char *chan_mix[] = {
266 	"L R",
267 	"L+R",
268 	"R L",
269 };
270 
271 static const struct soc_enum cs42l51_chan_mix =
272 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix);
273 
274 static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
275 	SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
276 			CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
277 			7, 0xffffff99, 0x18, adc_pcm_tlv),
278 	SOC_DOUBLE_R("PCM Playback Switch",
279 			CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
280 	SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
281 			CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
282 			8, 0xffffff19, 0x18, aout_tlv),
283 	SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
284 			CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
285 			7, 0xffffff99, 0x18, adc_pcm_tlv),
286 	SOC_DOUBLE_R("ADC Mixer Switch",
287 			CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
288 	SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
289 	SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
290 	SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
291 	SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0),
292 	SOC_DOUBLE_TLV("Mic Boost Volume",
293 			CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),
294 	SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),
295 	SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),
296 	SOC_ENUM_EXT("PCM channel mixer",
297 			cs42l51_chan_mix,
298 			cs42l51_get_chan_mix, cs42l51_set_chan_mix),
299 };
300 
301 /*
302  * to power down, one must:
303  * 1.) Enable the PDN bit
304  * 2.) enable power-down for the select channels
305  * 3.) disable the PDN bit.
306  */
307 static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
308 		struct snd_kcontrol *kcontrol, int event)
309 {
310 	unsigned long value;
311 
312 	value = snd_soc_read(w->codec, CS42L51_POWER_CTL1);
313 	value &= ~CS42L51_POWER_CTL1_PDN;
314 
315 	switch (event) {
316 	case SND_SOC_DAPM_PRE_PMD:
317 		value |= CS42L51_POWER_CTL1_PDN;
318 		break;
319 	default:
320 	case SND_SOC_DAPM_POST_PMD:
321 		break;
322 	}
323 	snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
324 		CS42L51_POWER_CTL1_PDN, value);
325 
326 	return 0;
327 }
328 
329 static const char *cs42l51_dac_names[] = {"Direct PCM",
330 	"DSP PCM", "ADC"};
331 static const struct soc_enum cs42l51_dac_mux_enum =
332 	SOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names);
333 static const struct snd_kcontrol_new cs42l51_dac_mux_controls =
334 	SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum);
335 
336 static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left",
337 	"MIC Left", "MIC+preamp Left"};
338 static const struct soc_enum cs42l51_adcl_mux_enum =
339 	SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names);
340 static const struct snd_kcontrol_new cs42l51_adcl_mux_controls =
341 	SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum);
342 
343 static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right",
344 	"MIC Right", "MIC+preamp Right"};
345 static const struct soc_enum cs42l51_adcr_mux_enum =
346 	SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names);
347 static const struct snd_kcontrol_new cs42l51_adcr_mux_controls =
348 	SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum);
349 
350 static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
351 	SND_SOC_DAPM_MICBIAS("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1),
352 	SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0,
353 		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
354 	SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0,
355 		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
356 	SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture",
357 		CS42L51_POWER_CTL1, 1, 1,
358 		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
359 	SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture",
360 		CS42L51_POWER_CTL1, 2, 1,
361 		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
362 	SND_SOC_DAPM_DAC_E("Left DAC", "Left HiFi Playback",
363 		CS42L51_POWER_CTL1, 5, 1,
364 		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
365 	SND_SOC_DAPM_DAC_E("Right DAC", "Right HiFi Playback",
366 		CS42L51_POWER_CTL1, 6, 1,
367 		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
368 
369 	/* analog/mic */
370 	SND_SOC_DAPM_INPUT("AIN1L"),
371 	SND_SOC_DAPM_INPUT("AIN1R"),
372 	SND_SOC_DAPM_INPUT("AIN2L"),
373 	SND_SOC_DAPM_INPUT("AIN2R"),
374 	SND_SOC_DAPM_INPUT("MICL"),
375 	SND_SOC_DAPM_INPUT("MICR"),
376 
377 	SND_SOC_DAPM_MIXER("Mic Preamp Left",
378 		CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0),
379 	SND_SOC_DAPM_MIXER("Mic Preamp Right",
380 		CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0),
381 
382 	/* HP */
383 	SND_SOC_DAPM_OUTPUT("HPL"),
384 	SND_SOC_DAPM_OUTPUT("HPR"),
385 
386 	/* mux */
387 	SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0,
388 		&cs42l51_dac_mux_controls),
389 	SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0,
390 		&cs42l51_adcl_mux_controls),
391 	SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0,
392 		&cs42l51_adcr_mux_controls),
393 };
394 
395 static const struct snd_soc_dapm_route cs42l51_routes[] = {
396 	{"HPL", NULL, "Left DAC"},
397 	{"HPR", NULL, "Right DAC"},
398 
399 	{"Left ADC", NULL, "Left PGA"},
400 	{"Right ADC", NULL, "Right PGA"},
401 
402 	{"Mic Preamp Left",  NULL,  "MICL"},
403 	{"Mic Preamp Right", NULL,  "MICR"},
404 
405 	{"PGA-ADC Mux Left",  "AIN1 Left",        "AIN1L" },
406 	{"PGA-ADC Mux Left",  "AIN2 Left",        "AIN2L" },
407 	{"PGA-ADC Mux Left",  "MIC Left",         "MICL"  },
408 	{"PGA-ADC Mux Left",  "MIC+preamp Left",  "Mic Preamp Left" },
409 	{"PGA-ADC Mux Right", "AIN1 Right",       "AIN1R" },
410 	{"PGA-ADC Mux Right", "AIN2 Right",       "AIN2R" },
411 	{"PGA-ADC Mux Right", "MIC Right",        "MICR" },
412 	{"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" },
413 
414 	{"Left PGA", NULL, "PGA-ADC Mux Left"},
415 	{"Right PGA", NULL, "PGA-ADC Mux Right"},
416 };
417 
418 static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
419 		unsigned int format)
420 {
421 	struct snd_soc_codec *codec = codec_dai->codec;
422 	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
423 	int ret = 0;
424 
425 	switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
426 	case SND_SOC_DAIFMT_I2S:
427 	case SND_SOC_DAIFMT_LEFT_J:
428 	case SND_SOC_DAIFMT_RIGHT_J:
429 		cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
430 		break;
431 	default:
432 		dev_err(codec->dev, "invalid DAI format\n");
433 		ret = -EINVAL;
434 	}
435 
436 	switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
437 	case SND_SOC_DAIFMT_CBM_CFM:
438 		cs42l51->func = MODE_MASTER;
439 		break;
440 	case SND_SOC_DAIFMT_CBS_CFS:
441 		cs42l51->func = MODE_SLAVE_AUTO;
442 		break;
443 	default:
444 		ret = -EINVAL;
445 		break;
446 	}
447 
448 	return ret;
449 }
450 
451 struct cs42l51_ratios {
452 	unsigned int ratio;
453 	unsigned char speed_mode;
454 	unsigned char mclk;
455 };
456 
457 static struct cs42l51_ratios slave_ratios[] = {
458 	{  512, CS42L51_QSM_MODE, 0 }, {  768, CS42L51_QSM_MODE, 0 },
459 	{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
460 	{ 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 },
461 	{  256, CS42L51_HSM_MODE, 0 }, {  384, CS42L51_HSM_MODE, 0 },
462 	{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },
463 	{ 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 },
464 	{  128, CS42L51_SSM_MODE, 0 }, {  192, CS42L51_SSM_MODE, 0 },
465 	{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },
466 	{  512, CS42L51_SSM_MODE, 0 }, {  768, CS42L51_SSM_MODE, 0 },
467 	{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },
468 	{  256, CS42L51_DSM_MODE, 0 }, {  384, CS42L51_DSM_MODE, 0 },
469 };
470 
471 static struct cs42l51_ratios slave_auto_ratios[] = {
472 	{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
473 	{ 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 },
474 	{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },
475 	{ 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 },
476 	{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },
477 	{  512, CS42L51_SSM_MODE, 1 }, {  768, CS42L51_SSM_MODE, 1 },
478 	{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },
479 	{  256, CS42L51_DSM_MODE, 1 }, {  384, CS42L51_DSM_MODE, 1 },
480 };
481 
482 static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
483 		int clk_id, unsigned int freq, int dir)
484 {
485 	struct snd_soc_codec *codec = codec_dai->codec;
486 	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
487 	struct cs42l51_ratios *ratios = NULL;
488 	int nr_ratios = 0;
489 	unsigned int rates = 0;
490 	unsigned int rate_min = -1;
491 	unsigned int rate_max = 0;
492 	int i;
493 
494 	cs42l51->mclk = freq;
495 
496 	switch (cs42l51->func) {
497 	case MODE_MASTER:
498 		return -EINVAL;
499 	case MODE_SLAVE:
500 		ratios = slave_ratios;
501 		nr_ratios = ARRAY_SIZE(slave_ratios);
502 		break;
503 	case MODE_SLAVE_AUTO:
504 		ratios = slave_auto_ratios;
505 		nr_ratios = ARRAY_SIZE(slave_auto_ratios);
506 		break;
507 	}
508 
509 	for (i = 0; i < nr_ratios; i++) {
510 		unsigned int rate = freq / ratios[i].ratio;
511 		rates |= snd_pcm_rate_to_rate_bit(rate);
512 		if (rate < rate_min)
513 			rate_min = rate;
514 		if (rate > rate_max)
515 			rate_max = rate;
516 	}
517 	rates &= ~SNDRV_PCM_RATE_KNOT;
518 
519 	if (!rates) {
520 		dev_err(codec->dev, "could not find a valid sample rate\n");
521 		return -EINVAL;
522 	}
523 
524 	codec_dai->playback.rates = rates;
525 	codec_dai->playback.rate_min = rate_min;
526 	codec_dai->playback.rate_max = rate_max;
527 
528 	codec_dai->capture.rates = rates;
529 	codec_dai->capture.rate_min = rate_min;
530 	codec_dai->capture.rate_max = rate_max;
531 
532 	return 0;
533 }
534 
535 static int cs42l51_hw_params(struct snd_pcm_substream *substream,
536 		struct snd_pcm_hw_params *params,
537 		struct snd_soc_dai *dai)
538 {
539 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
540 	struct snd_soc_device *socdev = rtd->socdev;
541 	struct snd_soc_codec *codec = socdev->card->codec;
542 	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
543 	int ret;
544 	unsigned int i;
545 	unsigned int rate;
546 	unsigned int ratio;
547 	struct cs42l51_ratios *ratios = NULL;
548 	int nr_ratios = 0;
549 	int intf_ctl, power_ctl, fmt;
550 
551 	switch (cs42l51->func) {
552 	case MODE_MASTER:
553 		return -EINVAL;
554 	case MODE_SLAVE:
555 		ratios = slave_ratios;
556 		nr_ratios = ARRAY_SIZE(slave_ratios);
557 		break;
558 	case MODE_SLAVE_AUTO:
559 		ratios = slave_auto_ratios;
560 		nr_ratios = ARRAY_SIZE(slave_auto_ratios);
561 		break;
562 	}
563 
564 	/* Figure out which MCLK/LRCK ratio to use */
565 	rate = params_rate(params);     /* Sampling rate, in Hz */
566 	ratio = cs42l51->mclk / rate;    /* MCLK/LRCK ratio */
567 	for (i = 0; i < nr_ratios; i++) {
568 		if (ratios[i].ratio == ratio)
569 			break;
570 	}
571 
572 	if (i == nr_ratios) {
573 		/* We did not find a matching ratio */
574 		dev_err(codec->dev, "could not find matching ratio\n");
575 		return -EINVAL;
576 	}
577 
578 	intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);
579 	power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);
580 
581 	intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
582 			| CS42L51_INTF_CTL_DAC_FORMAT(7));
583 	power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3)
584 			| CS42L51_MIC_POWER_CTL_MCLK_DIV2);
585 
586 	switch (cs42l51->func) {
587 	case MODE_MASTER:
588 		intf_ctl |= CS42L51_INTF_CTL_MASTER;
589 		power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
590 		break;
591 	case MODE_SLAVE:
592 		power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
593 		break;
594 	case MODE_SLAVE_AUTO:
595 		power_ctl |= CS42L51_MIC_POWER_CTL_AUTO;
596 		break;
597 	}
598 
599 	switch (cs42l51->audio_mode) {
600 	case SND_SOC_DAIFMT_I2S:
601 		intf_ctl |= CS42L51_INTF_CTL_ADC_I2S;
602 		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S);
603 		break;
604 	case SND_SOC_DAIFMT_LEFT_J:
605 		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
606 		break;
607 	case SND_SOC_DAIFMT_RIGHT_J:
608 		switch (params_format(params)) {
609 		case SNDRV_PCM_FORMAT_S16_LE:
610 		case SNDRV_PCM_FORMAT_S16_BE:
611 			fmt = CS42L51_DAC_DIF_RJ16;
612 			break;
613 		case SNDRV_PCM_FORMAT_S18_3LE:
614 		case SNDRV_PCM_FORMAT_S18_3BE:
615 			fmt = CS42L51_DAC_DIF_RJ18;
616 			break;
617 		case SNDRV_PCM_FORMAT_S20_3LE:
618 		case SNDRV_PCM_FORMAT_S20_3BE:
619 			fmt = CS42L51_DAC_DIF_RJ20;
620 			break;
621 		case SNDRV_PCM_FORMAT_S24_LE:
622 		case SNDRV_PCM_FORMAT_S24_BE:
623 			fmt = CS42L51_DAC_DIF_RJ24;
624 			break;
625 		default:
626 			dev_err(codec->dev, "unknown format\n");
627 			return -EINVAL;
628 		}
629 		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
630 		break;
631 	default:
632 		dev_err(codec->dev, "unknown format\n");
633 		return -EINVAL;
634 	}
635 
636 	if (ratios[i].mclk)
637 		power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
638 
639 	ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);
640 	if (ret < 0)
641 		return ret;
642 
643 	ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);
644 	if (ret < 0)
645 		return ret;
646 
647 	return 0;
648 }
649 
650 static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
651 {
652 	struct snd_soc_codec *codec = dai->codec;
653 	int reg;
654 	int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
655 
656 	reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);
657 
658 	if (mute)
659 		reg |= mask;
660 	else
661 		reg &= ~mask;
662 
663 	return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
664 }
665 
666 static struct snd_soc_dai_ops cs42l51_dai_ops = {
667 	.hw_params      = cs42l51_hw_params,
668 	.set_sysclk     = cs42l51_set_dai_sysclk,
669 	.set_fmt        = cs42l51_set_dai_fmt,
670 	.digital_mute   = cs42l51_dai_mute,
671 };
672 
673 struct snd_soc_dai cs42l51_dai = {
674 	.name = "CS42L51 HiFi",
675 	.playback = {
676 		.stream_name = "Playback",
677 		.channels_min = 1,
678 		.channels_max = 2,
679 		.rates = SNDRV_PCM_RATE_8000_96000,
680 		.formats = CS42L51_FORMATS,
681 	},
682 	.capture = {
683 		.stream_name = "Capture",
684 		.channels_min = 1,
685 		.channels_max = 2,
686 		.rates = SNDRV_PCM_RATE_8000_96000,
687 		.formats = CS42L51_FORMATS,
688 	},
689 	.ops = &cs42l51_dai_ops,
690 };
691 EXPORT_SYMBOL_GPL(cs42l51_dai);
692 
693 
694 static int cs42l51_probe(struct platform_device *pdev)
695 {
696 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
697 	struct snd_soc_codec *codec;
698 	int ret = 0;
699 
700 	if (!cs42l51_codec) {
701 		dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
702 		return -EINVAL;
703 	}
704 
705 	socdev->card->codec = cs42l51_codec;
706 	codec = socdev->card->codec;
707 
708 	/* Register PCMs */
709 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
710 	if (ret < 0) {
711 		dev_err(&pdev->dev, "failed to create PCMs\n");
712 		return ret;
713 	}
714 
715 	snd_soc_add_controls(codec, cs42l51_snd_controls,
716 		ARRAY_SIZE(cs42l51_snd_controls));
717 	snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
718 		ARRAY_SIZE(cs42l51_dapm_widgets));
719 	snd_soc_dapm_add_routes(codec, cs42l51_routes,
720 		ARRAY_SIZE(cs42l51_routes));
721 
722 	return 0;
723 }
724 
725 
726 static int cs42l51_remove(struct platform_device *pdev)
727 {
728 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
729 
730 	snd_soc_free_pcms(socdev);
731 	snd_soc_dapm_free(socdev);
732 
733 	return 0;
734 }
735 
736 struct snd_soc_codec_device soc_codec_device_cs42l51 = {
737 	.probe =	cs42l51_probe,
738 	.remove =	cs42l51_remove
739 };
740 EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
741 
742 static int __init cs42l51_init(void)
743 {
744 	int ret;
745 
746 	ret = i2c_add_driver(&cs42l51_i2c_driver);
747 	if (ret != 0) {
748 		printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
749 		return ret;
750 	}
751 	return 0;
752 }
753 module_init(cs42l51_init);
754 
755 static void __exit cs42l51_exit(void)
756 {
757 	i2c_del_driver(&cs42l51_i2c_driver);
758 }
759 module_exit(cs42l51_exit);
760 
761 MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
762 MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
763 MODULE_LICENSE("GPL");
764