2 * rt5623.c -- RT5623 ALSA SoC audio codec driver
4 * Copyright 2011 Realtek Semiconductor Corp.
5 * Author: Johnny Hsu <johnnyhsu@realtek.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/module.h>
13 #include <linux/moduleparam.h>
14 #include <linux/init.h>
15 #include <linux/delay.h>
17 #include <linux/i2c.h>
18 #include <linux/platform_device.h>
19 #include <linux/spi/spi.h>
20 #include <sound/core.h>
21 #include <sound/pcm.h>
22 #include <sound/pcm_params.h>
23 #include <sound/soc.h>
24 #include <sound/soc-dapm.h>
25 #include <sound/initval.h>
26 #include <sound/tlv.h>
30 static struct i2c_client *i2c_client;
32 static int codec_write(struct i2c_client *client, unsigned int reg,
39 data[1] = (value >> 8) & 0xff;
40 data[2] = value & 0xff;
42 //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,value);
43 if (i2c_master_send(client, data, 3) == 3)
49 static unsigned int codec_read(struct i2c_client *client,
52 struct i2c_msg xfer[2];
58 xfer[0].addr = client->addr;
64 xfer[1].addr = client->addr;
65 xfer[1].flags = I2C_M_RD;
67 xfer[1].buf = (u8 *)&data;
69 ret = i2c_transfer(client->adapter, xfer, 2);
71 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
74 //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,(data >> 8) | ((data & 0xff) << 8));
76 return (data >> 8) | ((data & 0xff) << 8);
84 static struct rt5623_reg init_data[] = {
85 {RT5623_PWR_MANAG_ADD3 , 0x8000},
86 {RT5623_PWR_MANAG_ADD2 , 0x2000},
87 {RT5623_LINE_IN_VOL , 0xe808},
88 {RT5623_STEREO_DAC_VOL , 0x6808},
89 {RT5623_OUTPUT_MIXER_CTRL , 0x1400},
90 {RT5623_ADC_REC_GAIN , 0xf58b},
91 {RT5623_ADC_REC_MIXER , 0x6f6f},
92 {RT5623_AUDIO_INTERFACE , 0x8000},
93 {RT5623_STEREO_AD_DA_CLK_CTRL , 0x0a2d},
94 {RT5623_PWR_MANAG_ADD1 , 0x8000},
95 {RT5623_PWR_MANAG_ADD2 , 0x27f3},
96 {RT5623_PWR_MANAG_ADD3 , 0x9c00},
97 {RT5623_SPK_OUT_VOL , 0x0000},
99 #define RT5623_INIT_REG_NUM ARRAY_SIZE(init_data)
101 static int rt5623_reg_init(struct i2c_client *client)
105 for (i = 0; i < RT5623_INIT_REG_NUM; i++)
106 codec_write(client, init_data[i].reg_index,
107 init_data[i].reg_value);
112 static int rt5623_reset(struct i2c_client *client)
114 return codec_write(client, RT5623_RESET, 0);
119 printk("enter %s\n",__func__);
120 rt5623_reset(i2c_client);
121 rt5623_reg_init(i2c_client);
123 EXPORT_SYMBOL(rt5623_on);
125 void rt5623_off(void)
127 printk("enter %s\n",__func__);
128 codec_write(i2c_client, RT5623_SPK_OUT_VOL, 0x8080);
129 rt5623_reset(i2c_client);
130 codec_write(i2c_client, RT5623_PWR_MANAG_ADD3, 0x0000);
131 codec_write(i2c_client, RT5623_PWR_MANAG_ADD2, 0x0000);
132 codec_write(i2c_client, RT5623_PWR_MANAG_ADD1, 0x0000);
134 EXPORT_SYMBOL(rt5623_off);
136 static const struct i2c_device_id rt5623_i2c_id[] = {
140 MODULE_DEVICE_TABLE(i2c, rt5623_i2c_id);
142 static int __devinit rt5623_i2c_probe(struct i2c_client *i2c,
143 const struct i2c_device_id *id)
145 pr_info("%s(%d)\n", __func__, __LINE__);
155 static int __devexit rt5623_i2c_remove(struct i2c_client *i2c)
160 struct i2c_driver rt5623_i2c_driver = {
163 .owner = THIS_MODULE,
165 .probe = rt5623_i2c_probe,
166 .remove = __devexit_p(rt5623_i2c_remove),
167 .id_table = rt5623_i2c_id,
170 static int __init rt5623_modinit(void)
172 return i2c_add_driver(&rt5623_i2c_driver);
174 module_init(rt5623_modinit);
176 static void __exit rt5623_modexit(void)
178 i2c_del_driver(&rt5623_i2c_driver);
180 module_exit(rt5623_modexit);
182 MODULE_DESCRIPTION("ASoC RT5623 driver");
183 MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
184 MODULE_LICENSE("GPL");