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>
33 static struct i2c_client *i2c_client;
36 static int codec_write(struct i2c_client *client, unsigned int reg,
42 data[1] = (value >> 8) & 0xff;
43 data[2] = value & 0xff;
45 //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,value);
46 if (i2c_master_send(client, data, 3) == 3)
52 static unsigned int codec_read(struct i2c_client *client,
55 struct i2c_msg xfer[2];
61 xfer[0].addr = client->addr;
65 xfer[0].scl_rate = 100 * 1000;
68 xfer[1].addr = client->addr;
69 xfer[1].flags = I2C_M_RD;
71 xfer[1].buf = (u8 *)&data;
72 xfer[1].scl_rate = 100 * 1000;
74 ret = i2c_transfer(client->adapter, xfer, 2);
76 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
79 //printk("%s: reg=0x%x value=0x%x\n",__func__,reg,(data >> 8) | ((data & 0xff) << 8));
81 return (data >> 8) | ((data & 0xff) << 8);
89 static struct rt5623_reg init_data[] = {
90 {RT5623_PWR_MANAG_ADD3 , 0x8000},
91 {RT5623_PWR_MANAG_ADD2 , 0x2000},
92 {RT5623_LINE_IN_VOL , 0xa808},
93 {RT5623_STEREO_DAC_VOL , 0x6808},
94 {RT5623_OUTPUT_MIXER_CTRL , 0x1400},
95 {RT5623_ADC_REC_GAIN , 0xf58b},
96 {RT5623_ADC_REC_MIXER , 0x7d7d},
97 {RT5623_AUDIO_INTERFACE , 0x8083},
98 {RT5623_STEREO_AD_DA_CLK_CTRL , 0x0a2d},
99 {RT5623_PWR_MANAG_ADD1 , 0x8000},
100 {RT5623_PWR_MANAG_ADD2 , 0xb7f3},
101 {RT5623_PWR_MANAG_ADD3 , 0x90c0},
102 {RT5623_SPK_OUT_VOL , 0x0000},
103 {RT5623_PLL_CTRL , 0x481f},
104 {RT5623_GLOBAL_CLK_CTRL_REG , 0x8000},
105 {RT5623_STEREO_AD_DA_CLK_CTRL , 0x3a2d},
107 #define RT5623_INIT_REG_NUM ARRAY_SIZE(init_data)
109 static int rt5623_reg_init(struct i2c_client *client)
113 for (i = 0; i < RT5623_INIT_REG_NUM; i++)
114 codec_write(client, init_data[i].reg_index,
115 init_data[i].reg_value);
120 static int rt5623_reset(struct i2c_client *client)
122 return codec_write(client, RT5623_RESET, 0);
127 if(status == MODEM_OFF)
129 printk("enter %s\n",__func__);
130 rt5623_reset(i2c_client);
131 rt5623_reg_init(i2c_client);
135 EXPORT_SYMBOL(rt5623_on);
137 void rt5623_off(void)
139 if(status == MODEM_ON)
141 printk("enter %s\n",__func__);
142 codec_write(i2c_client, RT5623_SPK_OUT_VOL, 0x8080);
143 rt5623_reset(i2c_client);
144 codec_write(i2c_client, RT5623_PWR_MANAG_ADD3, 0x0000);
145 codec_write(i2c_client, RT5623_PWR_MANAG_ADD2, 0x0000);
146 codec_write(i2c_client, RT5623_PWR_MANAG_ADD1, 0x0000);
150 EXPORT_SYMBOL(rt5623_off);
152 static const struct i2c_device_id rt5623_i2c_id[] = {
156 MODULE_DEVICE_TABLE(i2c, rt5623_i2c_id);
159 static int rt5623_i2c_probe(struct i2c_client *i2c,
160 const struct i2c_device_id *id)
162 pr_info("%s(%d)\n", __func__, __LINE__);
171 static int rt5623_i2c_remove(struct i2c_client *i2c)
176 struct i2c_driver rt5623_i2c_driver = {
179 .owner = THIS_MODULE,
181 .probe = rt5623_i2c_probe,
182 .remove = rt5623_i2c_remove,
183 .id_table = rt5623_i2c_id,
186 static int __init rt5623_modinit(void)
188 return i2c_add_driver(&rt5623_i2c_driver);
190 late_initcall(rt5623_modinit);
192 static void __exit rt5623_modexit(void)
194 i2c_del_driver(&rt5623_i2c_driver);
196 module_exit(rt5623_modexit);
198 MODULE_DESCRIPTION("ASoC RT5623 driver");
199 MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
200 MODULE_LICENSE("GPL");