1 #include <linux/module.h>
2 #include <linux/init.h>
4 #include <linux/device.h>
5 #include <linux/delay.h>
7 #include <linux/mfd/rk610_core.h>
9 #include <mach/iomux.h>
10 #include <linux/err.h>
11 #include <linux/slab.h>
13 #ifdef CONFIG_ARCH_RK30
14 #define RK610_RESET_PIN RK30_PIN0_PC6
16 #define RK610_RESET_PIN RK29_PIN6_PC1
23 #define DBG(x...) printk(KERN_INFO x)
28 static struct i2c_client *rk610_control_client = NULL;
29 #ifdef CONFIG_RK610_LCD
30 extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info);
32 int rk610_lcd_init(struct rk610_core_info *rk610_core_info){}
34 int rk610_control_send_byte(const char reg, const char data)
38 DBG("reg = 0x%02x, val=0x%02x\n", reg ,data);
40 if(rk610_control_client == NULL)
42 //i2c_master_reg8_send
43 ret = i2c_master_reg8_send(rk610_control_client, reg, &data, 1, 100*1000);
50 #ifdef CONFIG_SND_SOC_RK610
51 static unsigned int current_pll_value = 0;
52 int rk610_codec_pll_set(unsigned int rate)
58 if(current_pll_value == rate)
61 // Input clock is 12MHz.
62 if(rate == 11289600) {
63 // For 11.2896MHz, N = 2 M= 75 F = 0.264(0x43958) NO = 8
70 else if(rate == 12288000) {
71 // For 12.2888MHz, N = 2 M= 75 F = 0.92(0xEB851) NO = 8
79 printk(KERN_ERR "[%s] not support such frequency\n", __FUNCTION__);
83 //Enable codec pll fractional number and power down.
85 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
89 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON0, data);
92 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON1, data);
95 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON2, data);
96 data = (F >> 8) & 0xFF;
97 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON3, data);
98 data = (F >> 16) & 0xFF;
99 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON4, data);
101 // i2s mclk = codec_pll/5;
102 i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
103 data &= ~CLOCK_CON1_I2S_DVIDER_MASK;
105 rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
107 // Power up codec pll.
108 data |= C_PLL_POWER_ON;
109 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
111 current_pll_value = rate;
112 DBG("[%s] rate %u\n", __FUNCTION__, rate);
117 void rk610_control_init_codec(void)
119 struct i2c_client *client = rk610_control_client;
123 if(rk610_control_client == NULL)
125 DBG("[%s] start\n", __FUNCTION__);
127 //gpio_set_value(RK610_RESET_PIN, GPIO_LOW); //reset rk601
129 //gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
132 // Set i2c glitch timeout.
134 ret = i2c_master_reg8_send(client, RK610_CONTROL_REG_I2C_CON, &data, 1, 20*1000);
136 // rk610_codec_pll_set(11289600);
138 //use internal codec, enable DAC ADC LRCK output.
139 // i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
140 // data = CODEC_CON_BIT_DAC_LRCL_OUTPUT_DISABLE | CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
141 // data = CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
143 rk610_control_send_byte(RK610_CONTROL_REG_CODEC_CON, data);
145 // Select internal i2s clock from codec_pll.
146 i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
147 // data |= CLOCK_CON1_I2S_CLK_CODEC_PLL;
149 rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
151 i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
152 DBG("[%s] RK610_CONTROL_REG_CODEC_CON is %x\n", __FUNCTION__, data);
154 i2c_master_reg8_recv(client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
155 DBG("[%s] RK610_CONTROL_REG_CLOCK_CON1 is %x\n", __FUNCTION__, data);
159 static int rk610_read_p0_reg(struct i2c_client *client, char reg, char *val)
161 return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
164 static int rk610_write_p0_reg(struct i2c_client *client, char reg, char *val)
166 return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
168 static ssize_t rk610_show_reg_attrs(struct device *dev,
169 struct device_attribute *attr,
175 struct i2c_client *client=rk610_control_client;
179 rk610_read_p0_reg(client, i, &val);
181 size += sprintf(buf+size,"\n>>>rk610_ctl %x:",i);
182 size += sprintf(buf+size," %2x",val);
187 static ssize_t rk610_store_reg_attrs(struct device *dev,
188 struct device_attribute *attr,
189 const char *buf, size_t size)
191 struct i2c_client *client=NULL;
192 static char val=0,reg=0;
193 client = rk610_control_client;
194 DBG("/**********rk610 reg config******/");
196 sscanf(buf, "%x%x", &val,®);
197 DBG("reg=%x val=%x\n",reg,val);
198 rk610_write_p0_reg(client, reg, &val);
203 static struct device_attribute rk610_attrs[] = {
204 __ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs),
208 static int rk610_control_probe(struct i2c_client *client,
209 const struct i2c_device_id *id)
213 struct rk610_core_info *core_info = NULL;
214 DBG("[%s] start\n", __FUNCTION__);
215 core_info = kmalloc(sizeof(struct rk610_core_info), GFP_KERNEL);
218 dev_err(&client->dev, ">> rk610 core inf kmalloc fail!");
221 memset(core_info, 0, sizeof(struct rk610_core_info));
223 iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
224 if (IS_ERR(iis_clk)) {
225 printk("failed to get i2s clk\n");
226 ret = PTR_ERR(iis_clk);
228 DBG("got i2s clk ok!\n");
230 clk_set_rate(iis_clk, 11289600);
231 #ifdef CONFIG_ARCH_RK29
232 rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
234 rk30_mux_api_set(GPIO0B0_I2S8CHCLK_NAME, GPIO0B_I2S_8CH_CLK);
239 rk610_control_client = client;
241 if(RK610_RESET_PIN != INVALID_GPIO) {
242 ret = gpio_request(RK610_RESET_PIN, "rk610 reset");
244 printk(KERN_ERR "rk610_control_probe request gpio fail\n");
247 DBG("rk610_control_probe request gpio ok\n");
248 gpio_direction_output(RK610_RESET_PIN, GPIO_HIGH);
249 gpio_direction_output(RK610_RESET_PIN, GPIO_LOW);
251 gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
254 core_info->client = client;
255 rk610_lcd_init(core_info);
257 device_create_file(&(client->dev), &rk610_attrs[0]);
262 static int rk610_control_remove(struct i2c_client *client)
267 static const struct i2c_device_id rk610_control_id[] = {
271 MODULE_DEVICE_TABLE(i2c, rk610_control_id);
273 static struct i2c_driver rk610_control_driver = {
277 .probe = rk610_control_probe,
278 .remove = rk610_control_remove,
279 .id_table = rk610_control_id,
282 static int __init rk610_control_init(void)
284 DBG("[%s] start\n", __FUNCTION__);
285 return i2c_add_driver(&rk610_control_driver);
288 static void __exit rk610_control_exit(void)
290 i2c_del_driver(&rk610_control_driver);
293 subsys_initcall_sync(rk610_control_init);
294 //module_init(rk610_control_init);
295 module_exit(rk610_control_exit);
298 MODULE_DESCRIPTION("RK610 control driver");
299 MODULE_AUTHOR("Rock-chips, <www.rock-chips.com>");
300 MODULE_LICENSE("GPL");