cs42l51.c (e199e6136ce6b151e6638ae93dca60748424d900) cs42l51.c (697378972d075e1b26ed2935bf44fb828c6191f5)
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

--- 28 unchanged lines hidden (view full) ---

37
38enum master_slave_mode {
39 MODE_SLAVE,
40 MODE_SLAVE_AUTO,
41 MODE_MASTER,
42};
43
44struct cs42l51_private {
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

--- 28 unchanged lines hidden (view full) ---

37
38enum master_slave_mode {
39 MODE_SLAVE,
40 MODE_SLAVE_AUTO,
41 MODE_MASTER,
42};
43
44struct cs42l51_private {
45 enum snd_soc_control_type control_type;
46 void *control_data;
45 unsigned int mclk;
46 unsigned int audio_mode; /* The mode (I2S or left-justified) */
47 enum master_slave_mode func;
47 unsigned int mclk;
48 unsigned int audio_mode; /* The mode (I2S or left-justified) */
49 enum master_slave_mode func;
48 struct snd_soc_codec codec;
49 u8 reg_cache[CS42L51_NUMREGS];
50};
51
50 u8 reg_cache[CS42L51_NUMREGS];
51};
52
52static 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
60static int cs42l51_fill_cache(struct snd_soc_codec *codec)
61{

--- 8 unchanged lines hidden (view full) ---

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
53#define CS42L51_FORMATS ( \
54 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
55 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
56 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
57 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
58
59static int cs42l51_fill_cache(struct snd_soc_codec *codec)
60{

--- 8 unchanged lines hidden (view full) ---

69 "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
70 i2c_client->addr, length, CS42L51_NUMREGS);
71 return -EIO;
72 }
73
74 return 0;
75}
76
78static 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
171error_reg:
172 snd_soc_unregister_codec(codec);
173error_alloc:
174 kfree(cs42l51);
175error:
176 return ret;
177}
178
179static 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
190static const struct i2c_device_id cs42l51_id[] = {
191 {"cs42l51", 0},
192 {}
193};
194MODULE_DEVICE_TABLE(i2c, cs42l51_id);
195
196static 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
206static 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:

--- 265 unchanged lines hidden (view full) ---

479 { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 },
480};
481
482static 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);
77static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
78 struct snd_ctl_elem_value *ucontrol)
79{
80 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
81 unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
82
83 switch (value) {
84 default:

--- 265 unchanged lines hidden (view full) ---

350 { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 },
351};
352
353static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
354 int clk_id, unsigned int freq, int dir)
355{
356 struct snd_soc_codec *codec = codec_dai->codec;
357 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;
358
359 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
535static 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;
360 return 0;
361}
362
363static int cs42l51_hw_params(struct snd_pcm_substream *substream,
364 struct snd_pcm_hw_params *params,
365 struct snd_soc_dai *dai)
366{
367 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;
368 struct snd_soc_codec *codec = rtd->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;

--- 115 unchanged lines hidden (view full) ---

665
666static 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
369 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
370 int ret;
371 unsigned int i;
372 unsigned int rate;
373 unsigned int ratio;
374 struct cs42l51_ratios *ratios = NULL;
375 int nr_ratios = 0;
376 int intf_ctl, power_ctl, fmt;

--- 115 unchanged lines hidden (view full) ---

492
493static struct snd_soc_dai_ops cs42l51_dai_ops = {
494 .hw_params = cs42l51_hw_params,
495 .set_sysclk = cs42l51_set_dai_sysclk,
496 .set_fmt = cs42l51_set_dai_fmt,
497 .digital_mute = cs42l51_dai_mute,
498};
499
673struct snd_soc_dai cs42l51_dai = {
674 .name = "CS42L51 HiFi",
500static struct snd_soc_dai_driver cs42l51_dai = {
501 .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};
502 .playback = {
503 .stream_name = "Playback",
504 .channels_min = 1,
505 .channels_max = 2,
506 .rates = SNDRV_PCM_RATE_8000_96000,
507 .formats = CS42L51_FORMATS,
508 },
509 .capture = {
510 .stream_name = "Capture",
511 .channels_min = 1,
512 .channels_max = 2,
513 .rates = SNDRV_PCM_RATE_8000_96000,
514 .formats = CS42L51_FORMATS,
515 },
516 .ops = &cs42l51_dai_ops,
517};
691EXPORT_SYMBOL_GPL(cs42l51_dai);
692
518
693
694static int cs42l51_probe(struct platform_device *pdev)
519static int cs42l51_probe(struct snd_soc_codec *codec)
695{
520{
696 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
697 struct snd_soc_codec *codec;
698 int ret = 0;
521 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
522 int ret, reg;
699
523
700 if (!cs42l51_codec) {
701 dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
702 return -EINVAL;
524 codec->control_data = cs42l51->control_data;
525
526 ret = cs42l51_fill_cache(codec);
527 if (ret < 0) {
528 dev_err(codec->dev, "failed to fill register cache\n");
529 return ret;
703 }
704
530 }
531
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);
532 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
710 if (ret < 0) {
533 if (ret < 0) {
711 dev_err(&pdev->dev, "failed to create PCMs\n");
534 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
712 return ret;
713 }
714
535 return ret;
536 }
537
538 /*
539 * DAC configuration
540 * - Use signal processor
541 * - auto mute
542 * - vol changes immediate
543 * - no de-emphasize
544 */
545 reg = CS42L51_DAC_CTL_DATA_SEL(1)
546 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
547 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
548 if (ret < 0)
549 return ret;
550
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
551 snd_soc_add_controls(codec, cs42l51_snd_controls,
552 ARRAY_SIZE(cs42l51_snd_controls));
553 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
554 ARRAY_SIZE(cs42l51_dapm_widgets));
555 snd_soc_dapm_add_routes(codec, cs42l51_routes,
556 ARRAY_SIZE(cs42l51_routes));
557
558 return 0;
559}
560
561static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
562 .probe = cs42l51_probe,
563 .reg_cache_size = CS42L51_NUMREGS,
564 .reg_word_size = sizeof(u8),
565};
725
566
726static int cs42l51_remove(struct platform_device *pdev)
567static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
568 const struct i2c_device_id *id)
727{
569{
728 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
570 struct cs42l51_private *cs42l51;
571 int ret;
729
572
730 snd_soc_free_pcms(socdev);
731 snd_soc_dapm_free(socdev);
573 /* Verify that we have a CS42L51 */
574 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
575 if (ret < 0) {
576 dev_err(&i2c_client->dev, "failed to read I2C\n");
577 goto error;
578 }
732
579
580 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
581 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
582 dev_err(&i2c_client->dev, "Invalid chip id\n");
583 ret = -ENODEV;
584 goto error;
585 }
586
587 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
588 ret & 7);
589
590 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
591 if (!cs42l51) {
592 dev_err(&i2c_client->dev, "could not allocate codec\n");
593 return -ENOMEM;
594 }
595
596 i2c_set_clientdata(i2c_client, cs42l51);
597 cs42l51->control_data = i2c_client;
598 cs42l51->control_type = SND_SOC_I2C;
599
600 ret = snd_soc_register_codec(&i2c_client->dev,
601 &soc_codec_device_cs42l51, &cs42l51_dai, 1);
602 if (ret < 0)
603 kfree(cs42l51);
604error:
605 return ret;
606}
607
608static int cs42l51_i2c_remove(struct i2c_client *client)
609{
610 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
611
612 snd_soc_unregister_codec(&client->dev);
613 kfree(cs42l51);
733 return 0;
734}
735
614 return 0;
615}
616
736struct snd_soc_codec_device soc_codec_device_cs42l51 = {
737 .probe = cs42l51_probe,
738 .remove = cs42l51_remove
617static const struct i2c_device_id cs42l51_id[] = {
618 {"cs42l51", 0},
619 {}
739};
620};
740EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
621MODULE_DEVICE_TABLE(i2c, cs42l51_id);
741
622
623static struct i2c_driver cs42l51_i2c_driver = {
624 .driver = {
625 .name = "cs42l51-codec",
626 .owner = THIS_MODULE,
627 },
628 .id_table = cs42l51_id,
629 .probe = cs42l51_i2c_probe,
630 .remove = cs42l51_i2c_remove,
631};
632
742static 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}
753module_init(cs42l51_init);
754
755static void __exit cs42l51_exit(void)
756{
757 i2c_del_driver(&cs42l51_i2c_driver);
758}
759module_exit(cs42l51_exit);
760
633static int __init cs42l51_init(void)
634{
635 int ret;
636
637 ret = i2c_add_driver(&cs42l51_i2c_driver);
638 if (ret != 0) {
639 printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
640 return ret;
641 }
642 return 0;
643}
644module_init(cs42l51_init);
645
646static void __exit cs42l51_exit(void)
647{
648 i2c_del_driver(&cs42l51_i2c_driver);
649}
650module_exit(cs42l51_exit);
651
761MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
652MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
762MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
763MODULE_LICENSE("GPL");
653MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
654MODULE_LICENSE("GPL");