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>
12 #ifdef CONFIG_ARCH_RK30
13 #define RK610_RESET_PIN RK30_PIN0_PC6
15 #define RK610_RESET_PIN RK29_PIN6_PC1
22 #define DBG(x...) printk(KERN_INFO x)
27 static struct i2c_client *rk610_control_client = NULL;
28 #ifdef CONFIG_RK610_LCD
29 extern int rk610_lcd_init(struct i2c_client *client);
31 int rk610_lcd_init(struct i2c_client *client){}
33 int rk610_control_send_byte(const char reg, const char data)
37 DBG("reg = 0x%02x, val=0x%02x\n", reg ,data);
39 if(rk610_control_client == NULL)
41 //i2c_master_reg8_send
42 ret = i2c_master_reg8_send(rk610_control_client, reg, &data, 1, 100*1000);
49 #ifdef CONFIG_SND_SOC_RK610
50 static unsigned int current_pll_value = 0;
51 int rk610_codec_pll_set(unsigned int rate)
57 if(current_pll_value == rate)
60 // Input clock is 12MHz.
61 if(rate == 11289600) {
62 // For 11.2896MHz, N = 2 M= 75 F = 0.264(0x43958) NO = 8
69 else if(rate == 12288000) {
70 // For 12.2888MHz, N = 2 M= 75 F = 0.92(0xEB851) NO = 8
78 printk(KERN_ERR "[%s] not support such frequency\n", __FUNCTION__);
82 //Enable codec pll fractional number and power down.
84 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
88 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON0, data);
91 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON1, data);
94 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON2, data);
95 data = (F >> 8) & 0xFF;
96 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON3, data);
97 data = (F >> 16) & 0xFF;
98 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON4, data);
100 // i2s mclk = codec_pll/5;
101 i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
102 data &= ~CLOCK_CON1_I2S_DVIDER_MASK;
104 rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
106 // Power up codec pll.
107 data |= C_PLL_POWER_ON;
108 rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
110 current_pll_value = rate;
111 DBG("[%s] rate %u\n", __FUNCTION__, rate);
116 void rk610_control_init_codec(void)
118 struct i2c_client *client = rk610_control_client;
122 if(rk610_control_client == NULL)
124 DBG("[%s] start\n", __FUNCTION__);
126 //gpio_set_value(RK610_RESET_PIN, GPIO_LOW); //reset rk601
128 //gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
131 // Set i2c glitch timeout.
133 ret = i2c_master_reg8_send(client, RK610_CONTROL_REG_I2C_CON, &data, 1, 20*1000);
135 // rk610_codec_pll_set(11289600);
137 //use internal codec, enable DAC ADC LRCK output.
138 // i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
139 // data = CODEC_CON_BIT_DAC_LRCL_OUTPUT_DISABLE | CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
140 // data = CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
142 rk610_control_send_byte(RK610_CONTROL_REG_CODEC_CON, data);
144 // Select internal i2s clock from codec_pll.
145 i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
146 // data |= CLOCK_CON1_I2S_CLK_CODEC_PLL;
148 rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
150 i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
151 DBG("[%s] RK610_CONTROL_REG_CODEC_CON is %x\n", __FUNCTION__, data);
153 i2c_master_reg8_recv(client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
154 DBG("[%s] RK610_CONTROL_REG_CLOCK_CON1 is %x\n", __FUNCTION__, data);
157 #ifdef CONFIG_RK610_DEBUG
158 static int rk610_read_p0_reg(struct i2c_client *client, char reg, char *val)
160 return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
163 static int rk610_write_p0_reg(struct i2c_client *client, char reg, char *val)
165 return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
167 static ssize_t rk610_show_reg_attrs(struct device *dev,
168 struct device_attribute *attr,
174 struct i2c_client *client=rk610_control_client;
178 rk610_read_p0_reg(client, i, &val);
180 size += sprintf(buf+size,"\n>>>rk610_hdmi %x:",i);
181 size += sprintf(buf+size," %2x",val);
186 static ssize_t rk610_store_reg_attrs(struct device *dev,
187 struct device_attribute *attr,
188 const char *buf, size_t size)
190 struct i2c_client *client=NULL;
191 static char val=0,reg=0;
192 client = rk610_control_client;
193 DBG("/**********rk610 reg config******/");
195 sscanf(buf, "%x%x", &val,®);
196 DBG("reg=%x val=%x\n",reg,val);
197 rk610_write_p0_reg(client, reg, &val);
202 static struct device_attribute rk610_attrs[] = {
203 __ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs),
206 static int rk610_control_probe(struct i2c_client *client,
207 const struct i2c_device_id *id)
212 DBG("[%s] start\n", __FUNCTION__);
214 iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
215 if (IS_ERR(iis_clk)) {
216 printk("failed to get i2s clk\n");
217 ret = PTR_ERR(iis_clk);
219 DBG("got i2s clk ok!\n");
221 clk_set_rate(iis_clk, 11289600);
222 #ifdef CONFIG_ARCH_RK29
223 rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
225 rk30_mux_api_set(GPIO0B0_I2S8CHCLK_NAME, GPIO0B_I2S_8CH_CLK);
230 rk610_control_client = client;
232 if(RK610_RESET_PIN != INVALID_GPIO) {
233 ret = gpio_request(RK610_RESET_PIN, "rk610 reset");
235 printk(KERN_ERR "rk610_control_probe request gpio fail\n");
238 DBG("rk610_control_probe request gpio ok\n");
239 gpio_direction_output(RK610_RESET_PIN, GPIO_HIGH);
241 gpio_direction_output(RK610_RESET_PIN, GPIO_LOW);
243 gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
246 rk610_lcd_init(client);
247 #ifdef CONFIG_RK610_DEBUG
248 device_create_file(&(client->dev), &rk610_attrs[0]);
253 static int rk610_control_remove(struct i2c_client *client)
258 static const struct i2c_device_id rk610_control_id[] = {
262 MODULE_DEVICE_TABLE(i2c, rk610_control_id);
264 static struct i2c_driver rk610_control_driver = {
268 .probe = rk610_control_probe,
269 .remove = rk610_control_remove,
270 .id_table = rk610_control_id,
273 static int __init rk610_control_init(void)
275 DBG("[%s] start\n", __FUNCTION__);
276 return i2c_add_driver(&rk610_control_driver);
279 static void __exit rk610_control_exit(void)
281 i2c_del_driver(&rk610_control_driver);
284 fs_initcall(rk610_control_init);
285 //module_init(rk610_control_init);
286 module_exit(rk610_control_exit);
289 MODULE_DESCRIPTION("RK610 control driver");
290 MODULE_AUTHOR("Rock-chips, <www.rock-chips.com>");
291 MODULE_LICENSE("GPL");