~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/ak4642.c

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.11 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.84 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.154 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.201 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.201 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.77 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * ak4642.c  --  AK4642/AK4643 ALSA Soc Audio driver
  3  *
  4  * Copyright (C) 2009 Renesas Solutions Corp.
  5  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
  6  *
  7  * Based on wm8731.c by Richard Purdie
  8  * Based on ak4535.c by Richard Purdie
  9  * Based on wm8753.c by Liam Girdwood
 10  *
 11  * This program is free software; you can redistribute it and/or modify
 12  * it under the terms of the GNU General Public License version 2 as
 13  * published by the Free Software Foundation.
 14  */
 15 
 16 /* ** CAUTION **
 17  *
 18  * This is very simple driver.
 19  * It can use headphone output / stereo input only
 20  *
 21  * AK4642 is not tested.
 22  * AK4643 is tested.
 23  */
 24 
 25 #include <linux/module.h>
 26 #include <linux/moduleparam.h>
 27 #include <linux/init.h>
 28 #include <linux/delay.h>
 29 #include <linux/pm.h>
 30 #include <linux/i2c.h>
 31 #include <linux/platform_device.h>
 32 #include <sound/core.h>
 33 #include <sound/pcm.h>
 34 #include <sound/pcm_params.h>
 35 #include <sound/soc.h>
 36 #include <sound/soc-dapm.h>
 37 #include <sound/initval.h>
 38 
 39 #include "ak4642.h"
 40 
 41 #define AK4642_VERSION "0.0.1"
 42 
 43 #define PW_MGMT1        0x00
 44 #define PW_MGMT2        0x01
 45 #define SG_SL1          0x02
 46 #define SG_SL2          0x03
 47 #define MD_CTL1         0x04
 48 #define MD_CTL2         0x05
 49 #define TIMER           0x06
 50 #define ALC_CTL1        0x07
 51 #define ALC_CTL2        0x08
 52 #define L_IVC           0x09
 53 #define L_DVC           0x0a
 54 #define ALC_CTL3        0x0b
 55 #define R_IVC           0x0c
 56 #define R_DVC           0x0d
 57 #define MD_CTL3         0x0e
 58 #define MD_CTL4         0x0f
 59 #define PW_MGMT3        0x10
 60 #define DF_S            0x11
 61 #define FIL3_0          0x12
 62 #define FIL3_1          0x13
 63 #define FIL3_2          0x14
 64 #define FIL3_3          0x15
 65 #define EQ_0            0x16
 66 #define EQ_1            0x17
 67 #define EQ_2            0x18
 68 #define EQ_3            0x19
 69 #define EQ_4            0x1a
 70 #define EQ_5            0x1b
 71 #define FIL1_0          0x1c
 72 #define FIL1_1          0x1d
 73 #define FIL1_2          0x1e
 74 #define FIL1_3          0x1f
 75 #define PW_MGMT4        0x20
 76 #define MD_CTL5         0x21
 77 #define LO_MS           0x22
 78 #define HP_MS           0x23
 79 #define SPK_MS          0x24
 80 
 81 #define AK4642_CACHEREGNUM      0x25
 82 
 83 struct snd_soc_codec_device soc_codec_dev_ak4642;
 84 
 85 /* codec private data */
 86 struct ak4642_priv {
 87         struct snd_soc_codec codec;
 88         unsigned int sysclk;
 89 };
 90 
 91 static struct snd_soc_codec *ak4642_codec;
 92 
 93 /*
 94  * ak4642 register cache
 95  */
 96 static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
 97         0x00, 0x00, 0x01, 0x00,
 98         0x02, 0x00, 0x00, 0x00,
 99         0xe1, 0xe1, 0x18, 0x00,
100         0xe1, 0x18, 0x11, 0x08,
101         0x00, 0x00, 0x00, 0x00,
102         0x00, 0x00, 0x00, 0x00,
103         0x00, 0x00, 0x00, 0x00,
104         0x00, 0x00, 0x00, 0x00,
105         0x00, 0x00, 0x00, 0x00,
106         0x00,
107 };
108 
109 /*
110  * read ak4642 register cache
111  */
112 static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec,
113         unsigned int reg)
114 {
115         u16 *cache = codec->reg_cache;
116         if (reg >= AK4642_CACHEREGNUM)
117                 return -1;
118         return cache[reg];
119 }
120 
121 /*
122  * write ak4642 register cache
123  */
124 static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec,
125         u16 reg, unsigned int value)
126 {
127         u16 *cache = codec->reg_cache;
128         if (reg >= AK4642_CACHEREGNUM)
129                 return;
130 
131         cache[reg] = value;
132 }
133 
134 /*
135  * write to the AK4642 register space
136  */
137 static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg,
138         unsigned int value)
139 {
140         u8 data[2];
141 
142         /* data is
143          *   D15..D8 AK4642 register offset
144          *   D7...D0 register data
145          */
146         data[0] = reg & 0xff;
147         data[1] = value & 0xff;
148 
149         if (codec->hw_write(codec->control_data, data, 2) == 2) {
150                 ak4642_write_reg_cache(codec, reg, value);
151                 return 0;
152         } else
153                 return -EIO;
154 }
155 
156 static int ak4642_sync(struct snd_soc_codec *codec)
157 {
158         u16 *cache = codec->reg_cache;
159         int i, r = 0;
160 
161         for (i = 0; i < AK4642_CACHEREGNUM; i++)
162                 r |= ak4642_write(codec, i, cache[i]);
163 
164         return r;
165 };
166 
167 static int ak4642_dai_startup(struct snd_pcm_substream *substream,
168                               struct snd_soc_dai *dai)
169 {
170         int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
171         struct snd_soc_codec *codec = dai->codec;
172 
173         if (is_play) {
174                 /*
175                  * start headphone output
176                  *
177                  * PLL, Master Mode
178                  * Audio I/F Format :MSB justified (ADC & DAC)
179                  * Sampling Frequency: 44.1kHz
180                  * Digital Volume: −8dB
181                  * Bass Boost Level : Middle
182                  *
183                  * This operation came from example code of
184                  * "ASAHI KASEI AK4642" (japanese) manual p97.
185                  *
186                  * Example code use 0x39, 0x79 value for 0x01 address,
187                  * But we need MCKO (0x02) bit now
188                  */
189                 ak4642_write(codec, 0x05, 0x27);
190                 ak4642_write(codec, 0x0f, 0x09);
191                 ak4642_write(codec, 0x0e, 0x19);
192                 ak4642_write(codec, 0x09, 0x91);
193                 ak4642_write(codec, 0x0c, 0x91);
194                 ak4642_write(codec, 0x0a, 0x28);
195                 ak4642_write(codec, 0x0d, 0x28);
196                 ak4642_write(codec, 0x00, 0x64);
197                 ak4642_write(codec, 0x01, 0x3b); /* + MCKO bit */
198                 ak4642_write(codec, 0x01, 0x7b); /* + MCKO bit */
199         } else {
200                 /*
201                  * start stereo input
202                  *
203                  * PLL Master Mode
204                  * Audio I/F Format:MSB justified (ADC & DAC)
205                  * Sampling Frequency:44.1kHz
206                  * Pre MIC AMP:+20dB
207                  * MIC Power On
208                  * ALC setting:Refer to Table 35
209                  * ALC bit=“1”
210                  *
211                  * This operation came from example code of
212                  * "ASAHI KASEI AK4642" (japanese) manual p94.
213                  */
214                 ak4642_write(codec, 0x05, 0x27);
215                 ak4642_write(codec, 0x02, 0x05);
216                 ak4642_write(codec, 0x06, 0x3c);
217                 ak4642_write(codec, 0x08, 0xe1);
218                 ak4642_write(codec, 0x0b, 0x00);
219                 ak4642_write(codec, 0x07, 0x21);
220                 ak4642_write(codec, 0x00, 0x41);
221                 ak4642_write(codec, 0x10, 0x01);
222         }
223 
224         return 0;
225 }
226 
227 static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
228                                struct snd_soc_dai *dai)
229 {
230         int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
231         struct snd_soc_codec *codec = dai->codec;
232 
233         if (is_play) {
234                 /* stop headphone output */
235                 ak4642_write(codec, 0x01, 0x3b);
236                 ak4642_write(codec, 0x01, 0x0b);
237                 ak4642_write(codec, 0x00, 0x40);
238                 ak4642_write(codec, 0x0e, 0x11);
239                 ak4642_write(codec, 0x0f, 0x08);
240         } else {
241                 /* stop stereo input */
242                 ak4642_write(codec, 0x00, 0x40);
243                 ak4642_write(codec, 0x10, 0x00);
244                 ak4642_write(codec, 0x07, 0x01);
245         }
246 }
247 
248 static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
249         int clk_id, unsigned int freq, int dir)
250 {
251         struct snd_soc_codec *codec = codec_dai->codec;
252         struct ak4642_priv *ak4642 = codec->private_data;
253 
254         ak4642->sysclk = freq;
255         return 0;
256 }
257 
258 static struct snd_soc_dai_ops ak4642_dai_ops = {
259         .startup        = ak4642_dai_startup,
260         .shutdown       = ak4642_dai_shutdown,
261         .set_sysclk     = ak4642_dai_set_sysclk,
262 };
263 
264 struct snd_soc_dai ak4642_dai = {
265         .name = "AK4642",
266         .playback = {
267                 .stream_name = "Playback",
268                 .channels_min = 1,
269                 .channels_max = 2,
270                 .rates = SNDRV_PCM_RATE_8000_48000,
271                 .formats = SNDRV_PCM_FMTBIT_S16_LE },
272         .capture = {
273                 .stream_name = "Capture",
274                 .channels_min = 1,
275                 .channels_max = 2,
276                 .rates = SNDRV_PCM_RATE_8000_48000,
277                 .formats = SNDRV_PCM_FMTBIT_S16_LE },
278         .ops = &ak4642_dai_ops,
279 };
280 EXPORT_SYMBOL_GPL(ak4642_dai);
281 
282 static int ak4642_resume(struct platform_device *pdev)
283 {
284         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
285         struct snd_soc_codec *codec = socdev->card->codec;
286 
287         ak4642_sync(codec);
288         return 0;
289 }
290 
291 /*
292  * initialise the AK4642 driver
293  * register the mixer and dsp interfaces with the kernel
294  */
295 static int ak4642_init(struct ak4642_priv *ak4642)
296 {
297         struct snd_soc_codec *codec = &ak4642->codec;
298         int ret = 0;
299 
300         if (ak4642_codec) {
301                 dev_err(codec->dev, "Another ak4642 is registered\n");
302                 return -EINVAL;
303         }
304 
305         mutex_init(&codec->mutex);
306         INIT_LIST_HEAD(&codec->dapm_widgets);
307         INIT_LIST_HEAD(&codec->dapm_paths);
308 
309         codec->private_data     = ak4642;
310         codec->name             = "AK4642";
311         codec->owner            = THIS_MODULE;
312         codec->read             = ak4642_read_reg_cache;
313         codec->write            = ak4642_write;
314         codec->dai              = &ak4642_dai;
315         codec->num_dai          = 1;
316         codec->hw_write         = (hw_write_t)i2c_master_send;
317         codec->reg_cache_size   = ARRAY_SIZE(ak4642_reg);
318         codec->reg_cache        = kmemdup(ak4642_reg,
319                                           sizeof(ak4642_reg), GFP_KERNEL);
320 
321         if (!codec->reg_cache)
322                 return -ENOMEM;
323 
324         ak4642_dai.dev = codec->dev;
325         ak4642_codec = codec;
326 
327         ret = snd_soc_register_codec(codec);
328         if (ret) {
329                 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
330                 goto reg_cache_err;
331         }
332 
333         ret = snd_soc_register_dai(&ak4642_dai);
334         if (ret) {
335                 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
336                 snd_soc_unregister_codec(codec);
337                 goto reg_cache_err;
338         }
339 
340         /*
341          * clock setting
342          *
343          * Audio I/F Format: MSB justified (ADC & DAC)
344          * BICK frequency at Master Mode: 64fs
345          * Input Master Clock Select at PLL Mode: 11.2896MHz
346          * MCKO: Enable
347          * Sampling Frequency: 44.1kHz
348          *
349          * This operation came from example code of
350          * "ASAHI KASEI AK4642" (japanese) manual p89.
351          *
352          * please fix-me
353          */
354         ak4642_write(codec, 0x01, 0x08);
355         ak4642_write(codec, 0x04, 0x4a);
356         ak4642_write(codec, 0x05, 0x27);
357         ak4642_write(codec, 0x00, 0x40);
358         ak4642_write(codec, 0x01, 0x0b);
359 
360         return ret;
361 
362 reg_cache_err:
363         kfree(codec->reg_cache);
364         codec->reg_cache = NULL;
365 
366         return ret;
367 }
368 
369 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
370 static int ak4642_i2c_probe(struct i2c_client *i2c,
371                             const struct i2c_device_id *id)
372 {
373         struct ak4642_priv *ak4642;
374         struct snd_soc_codec *codec;
375         int ret;
376 
377         ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
378         if (!ak4642)
379                 return -ENOMEM;
380 
381         codec = &ak4642->codec;
382         codec->dev = &i2c->dev;
383 
384         i2c_set_clientdata(i2c, ak4642);
385         codec->control_data = i2c;
386 
387         ret = ak4642_init(ak4642);
388         if (ret < 0)
389                 printk(KERN_ERR "failed to initialise AK4642\n");
390 
391         return ret;
392 }
393 
394 static int ak4642_i2c_remove(struct i2c_client *client)
395 {
396         struct ak4642_priv *ak4642 = i2c_get_clientdata(client);
397 
398         snd_soc_unregister_dai(&ak4642_dai);
399         snd_soc_unregister_codec(&ak4642->codec);
400         kfree(ak4642->codec.reg_cache);
401         kfree(ak4642);
402         ak4642_codec = NULL;
403 
404         return 0;
405 }
406 
407 static const struct i2c_device_id ak4642_i2c_id[] = {
408         { "ak4642", 0 },
409         { "ak4643", 0 },
410         { }
411 };
412 MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
413 
414 static struct i2c_driver ak4642_i2c_driver = {
415         .driver = {
416                 .name = "AK4642 I2C Codec",
417                 .owner = THIS_MODULE,
418         },
419         .probe          = ak4642_i2c_probe,
420         .remove         = ak4642_i2c_remove,
421         .id_table       = ak4642_i2c_id,
422 };
423 
424 #endif
425 
426 static int ak4642_probe(struct platform_device *pdev)
427 {
428         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
429         int ret;
430 
431         if (!ak4642_codec) {
432                 dev_err(&pdev->dev, "Codec device not registered\n");
433                 return -ENODEV;
434         }
435 
436         socdev->card->codec = ak4642_codec;
437 
438         /* register pcms */
439         ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
440         if (ret < 0) {
441                 printk(KERN_ERR "ak4642: failed to create pcms\n");
442                 goto pcm_err;
443         }
444 
445         ret = snd_soc_init_card(socdev);
446         if (ret < 0) {
447                 printk(KERN_ERR "ak4642: failed to register card\n");
448                 goto card_err;
449         }
450 
451         dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
452         return ret;
453 
454 card_err:
455         snd_soc_free_pcms(socdev);
456         snd_soc_dapm_free(socdev);
457 pcm_err:
458         return ret;
459 
460 }
461 
462 /* power down chip */
463 static int ak4642_remove(struct platform_device *pdev)
464 {
465         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
466 
467         snd_soc_free_pcms(socdev);
468         snd_soc_dapm_free(socdev);
469 
470         return 0;
471 }
472 
473 struct snd_soc_codec_device soc_codec_dev_ak4642 = {
474         .probe =        ak4642_probe,
475         .remove =       ak4642_remove,
476         .resume =       ak4642_resume,
477 };
478 EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
479 
480 static int __init ak4642_modinit(void)
481 {
482         int ret;
483 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
484         ret = i2c_add_driver(&ak4642_i2c_driver);
485 #endif
486         return ret;
487 
488 }
489 module_init(ak4642_modinit);
490 
491 static void __exit ak4642_exit(void)
492 {
493 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
494         i2c_del_driver(&ak4642_i2c_driver);
495 #endif
496 
497 }
498 module_exit(ak4642_exit);
499 
500 MODULE_DESCRIPTION("Soc AK4642 driver");
501 MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
502 MODULE_LICENSE("GPL");
503 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp