rk616:add more control register defination
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rk616-core.c
1
2 #include <linux/kernel.h>
3 #include <linux/module.h>
4 #include <linux/delay.h>
5 #include <linux/mfd/core.h>
6 #include <linux/slab.h>
7 #include <linux/irq.h>
8 #include <linux/mfd/rk616.h>
9 #include <linux/clk.h>
10 #include <mach/iomux.h>
11 #include <linux/err.h>
12
13
14 static struct mfd_cell rk616_devs[] = {
15         {
16                 .name = "rk616-lvds",
17                 .id = 0,
18         },
19         {
20                 .name = "rk616-codec",
21                 .id = 1,
22         },
23         {
24                 .name = "rk616-hdmi",
25                 .id = 2,
26         },
27         {
28                 .name = "rk616-mipi",
29                 .id = 3,
30         },
31 };
32
33 static int rk616_i2c_read_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
34 {
35         struct i2c_client * client = rk616->client;
36         struct i2c_adapter *adap = client->adapter;
37         struct i2c_msg msgs[2];
38         int ret;
39         char reg_buf[2];
40         
41         memcpy(reg_buf, &reg, 2);
42
43         msgs[0].addr = client->addr;
44         msgs[0].flags = client->flags;
45         msgs[0].len = 2;
46         msgs[0].buf = reg_buf;
47         msgs[0].scl_rate = rk616->pdata->scl_rate;
48         msgs[0].udelay = client->udelay;
49
50         msgs[1].addr = client->addr;
51         msgs[1].flags = client->flags | I2C_M_RD;
52         msgs[1].len = 4;
53         msgs[1].buf = (char *)pval;
54         msgs[1].scl_rate = rk616->pdata->scl_rate;
55         msgs[1].udelay = client->udelay;
56
57         ret = i2c_transfer(adap, msgs, 2);
58
59         
60         return (ret == 2)? 4 : ret;
61
62 }
63
64 static int rk616_i2c_write_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
65 {
66         struct i2c_client *client = rk616->client;
67         struct i2c_adapter *adap = client->adapter;
68         struct i2c_msg msg;
69         int ret;
70         char *tx_buf = (char *)kmalloc(6, GFP_KERNEL);
71         if(!tx_buf)
72                 return -ENOMEM;
73         
74         memcpy(tx_buf, &reg, 2); 
75         memcpy(tx_buf+2, (char *)pval, 4); 
76
77         msg.addr = client->addr;
78         msg.flags = client->flags;
79         msg.len = 6;
80         msg.buf = (char *)tx_buf;
81         msg.scl_rate = rk616->pdata->scl_rate;
82         msg.udelay = client->udelay;
83
84         ret = i2c_transfer(adap, &msg, 1);
85         kfree(tx_buf);
86         
87         
88         return (ret == 1) ? 4 : ret;
89 }
90
91
92 static int rk616_clk_route_init(struct mfd_rk616 *rk616)
93 {
94
95         return 0;
96 }
97 static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
98 {
99         int ret;
100         struct mfd_rk616 *rk616 = NULL;
101         struct clk *iis_clk;
102
103         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
104         {
105                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
106                 ret = -ENODEV;
107         }
108         rk616 = kzalloc(sizeof(struct mfd_rk616), GFP_KERNEL);
109         if (rk616 == NULL)
110         {
111                 printk(KERN_ALERT "alloc for struct rk616 fail\n");
112                 ret = -ENOMEM;
113         }
114         
115         rk616->dev = &client->dev;
116         rk616->pdata = client->dev.platform_data;
117         rk616->client = client;
118         i2c_set_clientdata(client, rk616);
119         dev_set_drvdata(rk616->dev,rk616);
120         
121         if(rk616->pdata->power_init)
122                 rk616->pdata->power_init();
123
124 #if defined(CONFIG_SND_RK29_SOC_I2S_8CH)        
125         iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
126 #elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
127         iis_clk = clk_get_sys("rk29_i2s.1", "i2s");
128 #else
129         iis_clk = clk_get_sys("rk29_i2s.2", "i2s");
130 #endif
131         if (IS_ERR(iis_clk)) 
132         {
133                 dev_err(&client->dev,"failed to get i2s clk\n");
134                 ret = PTR_ERR(iis_clk);
135         }
136         else
137         {
138                 #if defined(CONFIG_ARCH_RK29)
139                 rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
140                 #else
141                 iomux_set(I2S0_CLK);
142                 #endif
143                 clk_enable(iis_clk);
144                 clk_set_rate(iis_clk, 11289600);
145                 clk_put(iis_clk);
146         }
147         rk616->read_dev = rk616_i2c_read_reg;
148         rk616->write_dev = rk616_i2c_write_reg;
149         ret = mfd_add_devices(rk616->dev, -1,
150                                       rk616_devs, ARRAY_SIZE(rk616_devs),
151                                       NULL, rk616->irq_base);
152         
153         dev_info(&client->dev,"rk616 core probe success!\n");
154         return 0;
155 }
156
157 static int __devexit rk616_i2c_remove(struct i2c_client *client)
158 {
159         return 0;
160 }
161
162 static const struct i2c_device_id id_table[] = {
163         {"rk616", 0 },
164         { }
165 };
166
167 static struct i2c_driver rk616_i2c_driver  = {
168         .driver = {
169                 .name  = "rk616",
170                 .owner = THIS_MODULE,
171         },
172         .probe          = &rk616_i2c_probe,
173         .remove         = &rk616_i2c_remove,
174         .id_table       = id_table,
175 };
176
177
178 static int __init rk616_module_init(void)
179 {
180         return i2c_add_driver(&rk616_i2c_driver);
181 }
182
183 static void __exit rk616_module_exit(void)
184 {
185         i2c_del_driver(&rk616_i2c_driver);
186 }
187
188 subsys_initcall_sync(rk616_module_init);
189 module_exit(rk616_module_exit);
190
191