1 /*
2 * Copyright (C) 2014 Rockchip Corporation.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
18 #include <linux/pm.h>
19 #include <linux/i2c.h>
20 #include <linux/spi/spi.h>
21 #include <linux/platform_device.h>
22 #include <linux/errno.h>
23 #include <linux/err.h>
24 #include <linux/debugfs.h>
25 #include "rk_headset.h"
26 #include <linux/of_gpio.h>
27 #include <linux/gpio.h>
28 #include <linux/iio/consumer.h>
29
30 /* Debug */
31 #if 0
32 #define DBG(x...) printk(x)
33 #else
34 #define DBG(x...) do { } while (0)
35 #endif
36
37 static struct rk_headset_pdata *pdata_info;
38
rockchip_headset_probe(struct platform_device * pdev)39 static int rockchip_headset_probe(struct platform_device *pdev)
40 {
41 struct device_node *node = pdev->dev.of_node;
42 struct rk_headset_pdata *pdata;
43 int ret;
44 enum of_gpio_flags flags;
45
46 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
47 if (!pdata) {
48 printk("%s failed to allocate driver data\n", __func__);
49 return -ENOMEM;
50 }
51 pdata_info = pdata;
52
53 /* headset */
54 ret = of_get_named_gpio_flags(node, "headset_gpio", 0, &flags);
55 if (ret < 0) {
56 dev_err(&pdev->dev, "Can not read property headset_gpio\n");
57 goto err;
58 } else {
59 pdata->headset_gpio = ret;
60 ret = devm_gpio_request(&pdev->dev, pdata->headset_gpio,
61 "headset_gpio");
62 if (ret < 0) {
63 dev_err(&pdev->dev, "headset_gpio request fail\n");
64 goto err;
65 }
66 ret = gpio_direction_input(pdata->headset_gpio);
67 if (ret < 0) {
68 dev_err(&pdev->dev,
69 "headset_gpio set direction fail\n");
70 goto err;
71 }
72 pdata->headset_insert_type = (flags & OF_GPIO_ACTIVE_LOW) ?
73 HEADSET_IN_LOW :
74 HEADSET_IN_HIGH;
75 }
76 /* hook */
77 ret = of_get_named_gpio_flags(node, "hook_gpio", 0, &pdata->hook_gpio);
78 if (ret < 0) {
79 dev_warn(&pdev->dev, "Can not read property hook_gpio\n");
80 pdata->hook_gpio = 0;
81 /* adc mode */
82 pdata->chan = iio_channel_get(&pdev->dev, NULL);
83 if (IS_ERR(pdata->chan)) {
84 pdata->chan = NULL;
85 dev_warn(&pdev->dev, "have not set adc chan\n");
86 }
87 } else {
88 ret = of_property_read_u32(node, "hook_down_type",
89 &pdata->hook_down_type);
90 if (ret < 0) {
91 dev_warn(&pdev->dev,
92 "have not set hook_down_type,set >hook< insert type low level default\n");
93 pdata->hook_down_type = 0;
94 }
95 ret = devm_gpio_request(&pdev->dev, pdata->hook_gpio,
96 "hook_gpio");
97 if (ret < 0) {
98 dev_warn(&pdev->dev,
99 "devm_gpio_request hook_gpio request ERROR\n");
100 goto err;
101 }
102 ret = gpio_direction_input(pdata->hook_gpio);
103 if (ret < 0) {
104 dev_warn(&pdev->dev,
105 "gpio_direction_input hook_gpio set ERROR\n");
106 goto err;
107 }
108 }
109
110 #ifdef CONFIG_MODEM_MIC_SWITCH
111 /* mic */
112 ret = of_get_named_gpio_flags(node, "mic_switch_gpio", 0, &flags);
113 if (ret < 0) {
114 DBG("%s() Can not read property mic_switch_gpio\n",
115 __func__);
116 } else {
117 pdata->headset_gpio = ret;
118 ret = of_property_read_u32(node, "hp_mic_io_value",
119 &pdata->hp_mic_io_value);
120 if (ret < 0) {
121 DBG("%s() have not set hp_mic_io_value ,so default set pull down low level\n",
122 __func__);
123 pdata->hp_mic_io_value = 0;
124 }
125 ret = of_property_read_u32(node, "main_mic_io_value",
126 &pdata->main_mic_io_value);
127 if (ret < 0) {
128 DBG("%s() have not set main_mic_io_value ,so default set pull down low level\n",
129 __func__);
130 pdata->main_mic_io_value = 1;
131 }
132 }
133 #endif
134 ret = of_property_read_u32(node, "rockchip,headset_wakeup",
135 &pdata->headset_wakeup);
136 if (ret < 0)
137 pdata->headset_wakeup = 1;
138 if (pdata->chan) { /* hook adc mode */
139 dev_info(&pdev->dev, "headset have hook adc mode\n");
140 ret = rk_headset_adc_probe(pdev, pdata);
141 if (ret < 0) {
142 goto err;
143 }
144 } else { /* hook interrupt mode and not hook */
145 dev_info(&pdev->dev, "headset have %s mode\n",
146 pdata->hook_gpio ? "interrupt hook" : "no hook");
147 ret = rk_headset_probe(pdev, pdata);
148 if (ret < 0) {
149 goto err;
150 }
151 }
152 return 0;
153 err:
154 return ret;
155 }
156
rockchip_headset_remove(struct platform_device * pdev)157 static int rockchip_headset_remove(struct platform_device *pdev)
158 {
159 return 0;
160 }
161
rockchip_headset_suspend(struct platform_device * pdev,pm_message_t state)162 static int rockchip_headset_suspend(struct platform_device *pdev,
163 pm_message_t state)
164 {
165 if (pdata_info->chan != 0) {
166 return rk_headset_adc_suspend(pdev, state);
167 }
168 return 0;
169 }
170
rockchip_headset_resume(struct platform_device * pdev)171 static int rockchip_headset_resume(struct platform_device *pdev)
172 {
173 if (pdata_info->chan != 0) {
174 return rk_headset_adc_resume(pdev);
175 }
176 return 0;
177 }
178
179 static const struct of_device_id rockchip_headset_of_match[] = {
180 { .compatible = "rockchip_headset", },
181 {},
182 };
183 MODULE_DEVICE_TABLE(of, rockchip_headset_of_match);
184
185 static struct platform_driver rockchip_headset_driver = {
186 .probe = rockchip_headset_probe,
187 .remove = rockchip_headset_remove,
188 .resume = rockchip_headset_resume,
189 .suspend = rockchip_headset_suspend,
190 .driver = {
191 .name = "rockchip_headset",
192 .owner = THIS_MODULE,
193 .of_match_table = of_match_ptr(rockchip_headset_of_match),
194 },
195 };
196
rockchip_headset_init(void)197 static int __init rockchip_headset_init(void)
198 {
199 platform_driver_register(&rockchip_headset_driver);
200 return 0;
201 }
202
rockchip_headset_exit(void)203 static void __exit rockchip_headset_exit(void)
204 {
205 platform_driver_unregister(&rockchip_headset_driver);
206 }
207 late_initcall(rockchip_headset_init);
208 module_exit(rockchip_headset_exit);
209
210 MODULE_DESCRIPTION("Rockchip Headset Core Driver");
211 MODULE_LICENSE("GPL");
212