fix section mismatch warnings
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / i2c / mt8127 / i2c_common.c
CommitLineData
6fa3eb70
S
1#include <linux/module.h>
2#include <linux/init.h>
3#include <linux/i2c.h>
4#include <linux/platform_device.h>
5#include <linux/dma-mapping.h>
6#include <linux/slab.h>
7#include <linux/errno.h>
8#include <linux/err.h>
9#include <mach/mt_pm_ldo.h>
10#include <mt_i2c.h>
11
12static char data_buffer[256 * 4];
13
14static ssize_t show_config(struct device *dev, struct device_attribute *attr, char *buff)
15{
16 int len = strlen(data_buffer);
17 memcpy(buff,data_buffer,len);
18 printk("Return Value:%s\n",data_buffer);
19 return len;
20}
21
22static int pows(int x, int y)
23{
24 int result = 1;
25 while (y--) result *=x;
26 return result;
27}
28
29int string2hex(const char * buffer, int cnt){
30 int c = 0;
31 char t = 0;
32 int count = cnt;
33 while (count--){
34 t = *(buffer + cnt - count - 1);
35 if ( t >= 'A' && t <= 'F') {
36 c += ((t - 'A') + 10 ) * pows(16,count);
37 } else if (t >= '0' && t <= '9'){
38 c += (t - '0') * pows(16,count);
39 } else {
40 c = -1;
41 }
42 }
43 return c;
44}
45
46char * get_hexbuffer(char *data_buffer, char *hex_buffer)
47{
48 char * ptr = data_buffer;
49 int index = 0;
50 while (*ptr && *++ptr) {
51 *(hex_buffer + index++) = string2hex(ptr-1, 2);
52 ptr++;
53 }
54 *(hex_buffer + index) = 0;
55 return hex_buffer;
56}
57
58int i2c_trans_data(int bus_id, int address, char *buf, int count, unsigned int ext_flag,int timing)
59{
60 int ret;
61
62 struct i2c_msg msg;
63 struct i2c_adapter *adap;
64 adap = i2c_get_adapter(bus_id);
65 if (!adap) return -1;
66
67 msg.addr = address;
68 msg.flags = ((ext_flag & 0x80000000)?I2C_M_RD:0);
69 msg.timing = timing;
70 msg.len = count;
71 msg.buf = (char *)buf;
72 msg.ext_flag = ext_flag & 0x7FFFFFFF;
73// msg.ext_flag = (ext_flag & 0x7FFF00FF);
74// msg.addr |= ext_flag & 0x0000FF00;
75 ret = i2c_transfer(adap, &msg, 1);
76
77 /* If everything went ok (i.e. 1 msg transmitted), return #bytes
78 transmitted, else error code. */
79 i2c_put_adapter(adap);
80 return (ret == 1) ? count : ret;
81}
82int mt_i2c_test(int id, int addr)
83{
84 int ret = 0;
85 unsigned long flag;
86 unsigned char buffer[]={0x55};
87 if(id >3)
88 flag = I2C_DIRECTION_FLAG;
89
90 flag |= 0x80000000;
91 ret = i2c_trans_data(id, addr,buffer,1,flag,200);
92 return ret;
93}
94EXPORT_SYMBOL(mt_i2c_test);
95
96//extern mt_i2c ;
97static int i2c_test_reg(int bus_id,int val)
98{
99 int ret=0;
100 struct i2c_adapter *adap;
101 mt_i2c *i2c;
102 adap = i2c_get_adapter(bus_id);
103 if (!adap) return -1;
104 i2c = container_of(adap,mt_i2c,adap);
105 printk("I2C%d base address %8x\n",bus_id,i2c->base);
106 //write i2c writable register with 0
107 i2c_writel(i2c,OFFSET_SLAVE_ADDR,val);
108 i2c_writel(i2c,OFFSET_INTR_MASK,val);
109 i2c_writel(i2c,OFFSET_INTR_STAT,val);
110 i2c_writel(i2c,OFFSET_CONTROL,val);
111 i2c_writel(i2c,OFFSET_TRANSFER_LEN,val);
112 i2c_writel(i2c,OFFSET_TRANSAC_LEN,val);
113 i2c_writel(i2c,OFFSET_DELAY_LEN,val);
114 i2c_writel(i2c,OFFSET_TIMING,val);
115 i2c_writel(i2c,OFFSET_EXT_CONF,val);
116 i2c_writel(i2c,OFFSET_IO_CONFIG,val);
117 i2c_writel(i2c,OFFSET_HS,val);
118 /* If everything went ok (i.e. 1 msg transmitted), return #bytes
119 transmitted, else error code. */
120 i2c_put_adapter(adap);
121 return ret;
122}
123static int i2c_soft_reset(int bus_id)
124{
125 int ret=0;
126 struct i2c_adapter *adap;
127 mt_i2c *i2c;
128 adap = i2c_get_adapter(bus_id);
129 if (!adap) return -1;
130 i2c = container_of(adap,mt_i2c,adap);
131 printk("I2C%d base address %8x\n",bus_id,i2c->base);
132 //write i2c writable register with 0
133 i2c_writel(i2c,OFFSET_SOFTRESET,1);
134 /* If everything went ok (i.e. 1 msg transmitted), return #bytes
135 transmitted, else error code. */
136 i2c_put_adapter(adap);
137 return ret;
138}
139static int i2c_ext_conf_test(int bus_id,int val)
140{
141 int ret=0;
142 struct i2c_adapter *adap;
143 mt_i2c *i2c;
144 adap = i2c_get_adapter(bus_id);
145 if (!adap) return -1;
146 i2c = container_of(adap,mt_i2c,adap);
147 printk("I2C%d base address %8x\n",bus_id,i2c->base);
148 //write i2c writable register with 0
149 i2c_writel(i2c,OFFSET_EXT_CONF,val);
150 printk("EXT_CONF 0x%x",i2c_readl(i2c,OFFSET_EXT_CONF));
151 /* If everything went ok (i.e. 1 msg transmitted), return #bytes
152 transmitted, else error code. */
153 i2c_put_adapter(adap);
154 return ret;
155}
156static void hex2string(unsigned char * in, unsigned char * out, int length)
157{
158 unsigned char * ptr = in;
159 unsigned char * ptrout = out;
160 unsigned char t;
161
162 while ( length-- ) {
163 t = (*ptr & 0xF0) >> 4 ;
164 if ( t < 10 ) *ptrout = t + '0';
165 else *ptrout = t + 'A' - 10;
166
167 ptrout++;
168
169 t = (*ptr & 0x0F);
170 if ( t < 10 ) *ptrout = t + '0';
171 else *ptrout = t + 'A' - 10;
172
173 ptr++;
174 ptrout++;
175 }
176 *ptrout = 0;
177}
178
179static ssize_t set_config(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
180{
181 int bus_id;
182 int address;
183 int operation;
184 int trans_mode;
185 int trans_stop;
186 int speed_mode;
187 int pushpull_mode;
188 int query_mode;
189 int timing;
190 int trans_num;
191 int trans_auxlen;
192 int dir=0;
193
194 int number = 0;
195 int length = 0;
196 unsigned int ext_flag = 0;
197 dma_addr_t dma_addr = 0;
198 void * vir_addr = NULL;
199 //int status;
200 int ret = 0;
201
202 unsigned char tmpbuffer[128];
203 printk("%s\n", buf);
204 //if ( sscanf(buf, "%d %d %d %d %d %d %d %d %d %d %d %d %s", &bus_id, &address, &operation, &trans_mode, &trans_stop, &speed_mode, &pushpull_mode, &query_mode, &timing, &trans_num, &trans_auxlen,&dir, data_buffer) ) {
4b9e9796 205 if ( sscanf(buf, "%d %x %d %d %d %d %d %d %d %d %d %1023s", &bus_id, &address, &operation, &trans_mode, &trans_stop, &speed_mode, &pushpull_mode, &query_mode, &timing, &trans_num, &trans_auxlen,data_buffer) ) {
6fa3eb70
S
206 if((address != 0)&&(operation<=2)){
207 length = strlen(data_buffer);
208 if (operation == 0){
209 ext_flag |= I2C_WR_FLAG;
210 number = (trans_auxlen << 8 ) | (length >> 1);
211 } else if (operation == 1) {
212 ext_flag |= 0x80000000;
213 number = (trans_num << 8 ) | (length >> 1);
214 } else if (operation == 2) {
215 ext_flag &= 0x7FFFFFFF;
216 number = (trans_num << 8 ) | (length >> 1);
217 } else {
218
219 printk("invalid operation\n");
220 goto err;
221 }
222 if(dir > 0)
223 ext_flag |= I2C_DIRECTION_FLAG;
224
225 if (trans_mode == 0){
226 //default is fifo
227 } else if (trans_mode == 1) {
228 ext_flag |= I2C_DMA_FLAG;
229 } else {
230
231 printk("invalid trans_mod fifo/dma\n");
232 goto err;
233 }
234
235 if (trans_stop == 0) {
236 //default
237 } else if (trans_stop == 1) {
238 ext_flag |= I2C_RS_FLAG;
239 } else {
240
241 printk("invalid trans_stop\n");
242 goto err;
243 }
244
245 if (speed_mode == 0) {
246 timing = 0;//ST mode
247 } else if (speed_mode == 1) {
248 //ext_flag |= I2C_FS_FLAG;//FS MODE
249 } else if (speed_mode == 2) {
250 ext_flag |= I2C_HS_FLAG;//HS mode
251 } else {
252 printk("invalid speed_mode\n");
253 goto err;
254 }
255
256 if (pushpull_mode == 0){
257 //default
258 } else if (pushpull_mode == 1) {
259 ext_flag |= I2C_PUSHPULL_FLAG;
260 } else {
261
262 printk("invalid pushpull mode\n");
263 goto err;
264 }
265
266 if ( query_mode == 0 ){
267 //
268 } else if (query_mode == 1) {
269 ext_flag |= I2C_POLLING_FLAG;
270 } else {
271
272 printk("invalid query mode interrupt/polling\n");
273 goto err;
274 }
275
276 if (trans_mode == 1) {/*DMA MODE*/
277 vir_addr = dma_alloc_coherent(NULL, length >> 1, &dma_addr, GFP_KERNEL);
278 if ( vir_addr == NULL ){
279
280 printk("alloc dma memory failed\n");
281 goto err;
282 }
283 } else {
284 vir_addr = kzalloc(length >> 1, GFP_KERNEL);
285 if ( vir_addr == NULL){
286
287 printk("alloc virtual memory failed\n");
288 goto err;
289 }
290 }
291
292 get_hexbuffer(data_buffer, vir_addr);
293 printk(KERN_ALERT"bus_id:%d,address:%x,count:%x,ext_flag:0x%x,timing:%d\n", bus_id,address,number,ext_flag,timing);
294 printk(KERN_ALERT"data_buffer:%s\n", data_buffer);
295
296 if ( trans_mode == 1 ){
297 /*DMA*/
298 ret = i2c_trans_data(bus_id, address, (void *)dma_addr, number, ext_flag, timing);
299 } else {
300 ret = i2c_trans_data(bus_id, address, vir_addr, number, ext_flag, timing);
301 }
302
303 //dealing
304
305 if ( ret >= 0) {
306
307 if ( operation == 1 ) {
308 hex2string(vir_addr, tmpbuffer, length >> 1);
309 sprintf(data_buffer, "1 %s", tmpbuffer);
310 } else if ( operation == 0 ){
311 hex2string(vir_addr, tmpbuffer, trans_auxlen);
312 sprintf(data_buffer, "1 %s", tmpbuffer);
313 } else {
314 sprintf(data_buffer, "1 %s", "00");
315 }
316 printk("Actual return Value:%d %p\n",ret, vir_addr);
317 } else if ( ret < 0 ) {
318
319 if ( ret == -EINVAL) {
320 sprintf(data_buffer, "0 %s", "Invalid Parameter");
321 } else if ( ret == -ETIMEDOUT ) {
322 sprintf(data_buffer, "0 %s", "Transfer Timeout");
323 } else if ( ret == -EREMOTEIO ) {
324 sprintf(data_buffer, "0 %s", "Ack Error");
325 } else {
326 sprintf(data_buffer, "0 %s", "unknow error");
327 }
328 printk("Actual return Value:%d %p\n",ret, vir_addr);
329 }
330
331 if (trans_mode == 1 && vir_addr != NULL) {/*DMA MODE*/
332 dma_free_coherent(NULL, length >> 1, vir_addr, dma_addr);
333 } else {
334 if (vir_addr)
335 kfree(vir_addr);
336 }
337 //log for UT test.
338 {
339 struct i2c_adapter *adap= i2c_get_adapter(bus_id);
340 mt_i2c *i2c = i2c_get_adapdata(adap);
341 _i2c_dump_info(i2c);
342 }
343 }else{
344 struct i2c_adapter *adap= i2c_get_adapter(bus_id);
345 mt_i2c *i2c = i2c_get_adapdata(adap);
346 if(operation == 3){
347 _i2c_dump_info(i2c);
348 }else if(operation == 4){
349 i2c_test_reg(bus_id,0);
350 _i2c_dump_info(i2c);
351 i2c_test_reg(bus_id,0xFFFFFFFF);
352 _i2c_dump_info(i2c);
353 }else if(operation == 5){
354 i2c_ext_conf_test(bus_id,address);
355 }else if(operation == 9){
356 i2c_soft_reset(bus_id);
357 _i2c_dump_info(i2c);
358 }else if(operation == 6){
359 if(bus_id == 0){
360 //I2C0 PINMUX2 power on
361 #ifdef CONFIG_MTK_PMIC_MT6397
362 #else
363 hwPowerOn(MT65XX_POWER_LDO_VMC1,VOL_DEFAULT,"i2c_pinmux");
364 hwPowerOn(MT65XX_POWER_LDO_VMCH1,VOL_DEFAULT,"i2c_pinmux");
365 #endif
366 }
367
368 }else if(operation == 7){
369 mt_i2c_test(1,0x50);
370 }else{
371 dev_err(dev, "i2c debug system: Parameter invalid!\n");
372 }
373 _i2c_dump_info(i2c);
374
375 }
376 } else {
377 /*parameter invalid*/
378 dev_err(dev, "i2c debug system: Parameter invalid!\n");
379 }
380
381 return count;
382err:
383 printk("analyze failed\n");
384 return -1;
385}
386
387static DEVICE_ATTR(ut, 660, show_config, set_config);
388
389static int __init i2c_common_probe(struct platform_device *pdev)
390{
391 int ret = 0;
392