rk fb: extend output mutex lock in win config
[firefly-linux-kernel-4.4.55.git] / drivers / input / misc / rk_board_id.c
1 #include <linux/kernel.h>\r
2 #include <linux/init.h>\r
3 #include <linux/platform_device.h>\r
4 #include <linux/input.h>\r
5 #include <linux/io.h>\r
6 #include <linux/delay.h>\r
7 #include <linux/i2c.h>\r
8 #include <linux/skbuff.h>\r
9 \r
10 #include <mach/board.h>\r
11 #include <mach/io.h>\r
12 #include <mach/gpio.h>\r
13 #include <mach/iomux.h>\r
14 \r
15 #include <linux/rk_board_id.h>\r
16 #if 0\r
17 #define DBG(x...)  printk(x)\r
18 #else\r
19 #define DBG(x...)\r
20 #endif\r
21 \r
22 extern void kernel_restart(char *cmd);\r
23 \r
24 struct board_id_private_data {\r
25         struct mutex id_mutex;\r
26         int last_value[16];\r
27         int board_id;\r
28         struct board_id_platform_data *pdata;\r
29 };\r
30 \r
31 static struct board_id_private_data *g_id;\r
32 \r
33 \r
34 enum rk_board_id rk_get_board_id(void)\r
35 {\r
36         struct board_id_private_data *id = g_id;\r
37         DBG("%s:id:0x%x\n",__func__,id->board_id);\r
38         return id->board_id;\r
39 }\r
40 EXPORT_SYMBOL(rk_get_board_id);\r
41 \r
42 static int _rk_get_board_id(struct board_id_private_data *id)\r
43 {\r
44         int result = 0;\r
45         int value1 = 0, value2 = 0, value3 = 0;\r
46         int i = 0, j = 0;\r
47         \r
48         id->board_id = -1;\r
49                         \r
50         for(i=0; i<id->pdata->num_gpio; i++)\r
51         {\r
52                 gpio_request(id->pdata->gpio_pin[i],"gpio_board_id");\r
53                 gpio_direction_input(id->pdata->gpio_pin[i]);\r
54                 gpio_pull_updown(id->pdata->gpio_pin[i], PullDisable);\r
55                 for(j=0; j<1000; j++)\r
56                 {\r
57                         value1 = gpio_get_value(id->pdata->gpio_pin[i]);\r
58                         if(value1 < 0)\r
59                                 continue;\r
60                         mdelay(1);\r
61                         value2 = gpio_get_value(id->pdata->gpio_pin[i]);\r
62                         if(value2 < 0)\r
63                                 continue;\r
64                         mdelay(1);\r
65                         value3 = gpio_get_value(id->pdata->gpio_pin[i]);\r
66                         if(value3 < 0)\r
67                                 continue;\r
68                         if((value1 == value2) && (value2 == value3))\r
69                                 break;\r
70                 }\r
71                 if(j >= 1000)\r
72                 {\r
73                         printk("%s:hareware error,gpio level changed always!\n");                       \r
74                         kernel_restart(NULL);\r
75                 }\r
76                 \r
77                 result = (value1 << i) | result;\r
78                 \r
79                 DBG("%s:gpio:%d,value:%d\n",__func__,id->pdata->gpio_pin[i],value1);\r
80         }\r
81 \r
82         id->board_id = result;\r
83 \r
84         \r
85         DBG("%s:num=%d,id=0x%x\n",__func__,id->pdata->num_gpio, id->board_id);\r
86 \r
87         return result;\r
88 }\r
89 \r
90 \r
91 static int __devinit rk_board_id_probe(struct platform_device *pdev)\r
92 {\r
93         struct board_id_platform_data *pdata = pdev->dev.platform_data;\r
94         struct board_id_private_data *id = NULL;\r
95         int result = 0;\r
96 \r
97         if(!pdata)\r
98                 return -ENOMEM;\r
99         \r
100         id = kzalloc(sizeof(struct board_id_private_data), GFP_KERNEL);\r
101         if (id == NULL) {\r
102                 dev_err(&pdev->dev, "Unable to allocate private data\n");\r
103                 return -ENOMEM;\r
104         }\r
105 \r
106         id->pdata = pdata;\r
107         \r
108         if(pdata->init_platform_hw)\r
109                 pdata->init_platform_hw();\r
110         \r
111         result = _rk_get_board_id(id);\r
112 \r
113         if(pdata->init_parameter)\r
114                 pdata->init_parameter(id->board_id);\r
115 \r
116         if(pdata->exit_platform_hw)\r
117                 pdata->exit_platform_hw();\r
118         \r
119         platform_set_drvdata(pdev, id); \r
120         g_id = id;\r
121         \r
122         printk("%s:board id :0x%x\n",__func__,result);\r
123         return 0;\r
124 }\r
125 \r
126 static int __devexit rk_board_id_remove(struct platform_device *pdev)\r
127 {\r
128         //struct board_id_platform_data *pdata = pdev->dev.platform_data;\r
129         struct board_id_private_data *id = platform_get_drvdata(pdev);\r
130         \r
131         kfree(id);\r
132         \r
133         return 0;\r
134 }\r
135 \r
136 static struct platform_driver rk_board_id_driver = {\r
137         .probe          = rk_board_id_probe,\r
138         .remove         = __devexit_p(rk_board_id_remove),\r
139         .driver         = {\r
140                 .name   = "rk-board-id",\r
141                 .owner  = THIS_MODULE,\r
142         },\r
143 };\r
144 \r
145 static int __init rk_get_board_init(void)\r
146 {\r
147         return platform_driver_register(&rk_board_id_driver);\r
148 }\r
149 \r
150 static void __exit rk_get_board_exit(void)\r
151 {\r
152         platform_driver_unregister(&rk_board_id_driver);\r
153 }\r
154 \r
155 arch_initcall_sync(rk_get_board_init);\r
156 module_exit(rk_get_board_exit);\r
157 \r
158 MODULE_AUTHOR("ROCKCHIP Corporation:lw@rock-chips.com");\r
159 MODULE_DESCRIPTION("Interface for get board id");\r
160 MODULE_LICENSE("GPL");\r