2 * bcm4751.c: Machine specific driver for GPS module
4 * Copyright (C) 2009-2010 Samsung Electronics
5 * Jaehoon Chung <jh80.chung@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/mutex.h>
18 #include <linux/err.h>
19 #include <linux/delay.h>
20 #include <linux/rfkill.h>
21 #include <linux/regulator/machine.h>
23 #include <mach/gpio.h>
25 #include <plat/gpio-cfg.h>
30 struct bcm4751_platform_data *pdata;
34 struct regulator *regulator;
37 static void bcm4751_enable(void *data)
39 struct bcm4751_data *bd = data;
40 struct bcm4751_platform_data *pdata = bd->pdata;
42 if (bd->regulator && !bd->regulator_state) {
43 regulator_enable(bd->regulator);
44 bd->regulator_state = true;
47 gpio_set_value(pdata->regpu, 1);
50 gpio_set_value(pdata->nrst, 1);
53 gpio_set_value(pdata->clk_int, 1);
58 static void bcm4751_disable(void *data)
60 struct bcm4751_data *bd = data;
61 struct bcm4751_platform_data *pdata = bd->pdata;
63 gpio_set_value(pdata->regpu, 0);
66 gpio_set_value(pdata->clk_int, 0);
68 if (bd->regulator && bd->regulator_state) {
69 regulator_disable(bd->regulator);
70 bd->regulator_state = false;
76 static int bcm4751_set_block(void *data, bool blocked)
79 printk(KERN_INFO "%s : Enable GPS chip\n", __func__);
82 printk(KERN_INFO "%s : Disable GPS chip\n", __func__);
83 bcm4751_disable(data);
88 static const struct rfkill_ops bcm4751_rfkill_ops = {
89 .set_block = bcm4751_set_block,
92 static int __devinit bcm4751_probe(struct platform_device *dev)
94 struct bcm4751_platform_data *pdata;
95 struct bcm4751_data *bd;
99 pdata = dev->dev.platform_data;
101 dev_err(&dev->dev, "No BCM4751 platform data.\n");
105 bd = kzalloc(sizeof(struct bcm4751_data), GFP_KERNEL);
115 gpio_request(gpio, "GPS_EN");
116 gpio_direction_output(gpio, 0);
121 /* GPS_nRST is high */
122 gpio_request(gpio, "GPS_nRST");
123 gpio_direction_output(gpio, 1);
128 s3c_gpio_setpull(pdata->uart_rxd, S3C_GPIO_PULL_UP);
130 if (pdata->clk_int) {
131 gpio = pdata->clk_int;
132 gpio_request(gpio, "GPS_CLK_INT");
133 gpio_direction_output(gpio, 0);
136 printk("%s: BCM4751 module is ready to start\n", __func__);
138 /* Register BCM4751 to RFKILL class */
139 bd->rfk = rfkill_alloc("bcm4751", &dev->dev, RFKILL_TYPE_GPS,
140 &bcm4751_rfkill_ops, bd);
146 bd->regulator = regulator_get(NULL, "gps_clk");
147 if (IS_ERR_OR_NULL(bd->regulator)) {
148 printk("BCM4751 regulator_get error\n");
152 bd->regulator_state = false;
155 * described by the comment in rfkill.h
159 rfkill_init_sw_state(bd->rfk, true);
162 ret = rfkill_register(bd->rfk);
166 platform_set_drvdata(dev, bd);
168 printk("%s: RFKILL module is ready to start\n", __func__);
173 rfkill_destroy(bd->rfk);
180 static int __devexit bcm4751_remove(struct platform_device *dev)
182 struct bcm4751_data *bd = platform_get_drvdata(dev);
183 struct bcm4751_platform_data *pdata = bd->pdata;
185 rfkill_unregister(bd->rfk);
186 rfkill_destroy(bd->rfk);
187 gpio_free(pdata->regpu);
188 gpio_free(pdata->nrst);
190 platform_set_drvdata(dev, NULL);
196 static int bcm4751_suspend(struct platform_device *dev, pm_message_t stata)
198 struct bcm4751_data *bd = platform_get_drvdata(dev);
199 struct bcm4751_platform_data *pdata = bd->pdata;
202 s5p_gpio_set_pdn_config(pdata->regpu, S3C_GPIO_PDNCFG_OUTPUT1);
203 s5p_gpio_set_pdn_config(pdata->nrst, S3C_GPIO_PDNCFG_OUTPUT1);
204 s5p_gpio_set_pdn_config(pdata->clk_int, S3C_GPIO_PDNCFG_OUTPUT1);
206 s5p_gpio_set_pdn_config(pdata->regpu, S3C_GPIO_PDNCFG_OUTPUT0);
207 s5p_gpio_set_pdn_config(pdata->nrst, S3C_GPIO_PDNCFG_OUTPUT0);
208 s5p_gpio_set_pdn_config(pdata->clk_int, S3C_GPIO_PDNCFG_OUTPUT0);
214 static int bcm4751_resume(struct platform_device *dev)
219 #define bcm4751_suspend NULL
220 #define bcm4751_resume NULL
223 static struct platform_driver bcm4751_driver = {
224 .probe = bcm4751_probe,
225 .remove = __devexit_p(bcm4751_remove),
226 .suspend = bcm4751_suspend,
227 .resume = bcm4751_resume,
233 static int __init bcm4751_init(void)
235 return platform_driver_register(&bcm4751_driver);
238 static void __exit bcm4751_exit(void)
240 platform_driver_unregister(&bcm4751_driver);
243 module_init(bcm4751_init);
244 module_exit(bcm4751_exit);
246 MODULE_AUTHOR("Jaehoon Chung <jh80.chung@samsung.com>");
247 MODULE_DESCRIPTION("BCM4751 GPS module driver");
248 MODULE_LICENSE("GPL");