2 * Copyright (C) 2011 Sony Ericsson Mobile Communications Inc.
4 * Author: Courtney Cavin <courtney.cavin@sonyericsson.com>
5 * Prepared for up-stream by: Oskar Andero <oskar.andero@sonyericsson.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/i2c.h>
13 #include <linux/irq.h>
14 #include <linux/slab.h>
15 #include <linux/input.h>
16 #include <linux/module.h>
17 #include <linux/interrupt.h>
18 #include <linux/gpio.h>
19 #include <linux/delay.h>
20 #include <linux/input/gp2ap002a00f.h>
23 struct input_dev
*input
;
24 const struct gp2a_platform_data
*pdata
;
25 struct i2c_client
*i2c_client
;
32 GP2A_ADDR_CYCLE
= 0x3,
33 GP2A_ADDR_OPMOD
= 0x4,
38 /* Software Shutdown control: 0 = shutdown, 1 = normal operation */
42 static int gp2a_report(struct gp2a_data
*dt
)
44 int vo
= gpio_get_value(dt
->pdata
->vout_gpio
);
46 input_report_switch(dt
->input
, SW_FRONT_PROXIMITY
, !vo
);
47 input_sync(dt
->input
);
52 static irqreturn_t
gp2a_irq(int irq
, void *handle
)
54 struct gp2a_data
*dt
= handle
;
61 static int gp2a_enable(struct gp2a_data
*dt
)
63 return i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_OPMOD
,
67 static int gp2a_disable(struct gp2a_data
*dt
)
69 return i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_OPMOD
,
73 static int gp2a_device_open(struct input_dev
*dev
)
75 struct gp2a_data
*dt
= input_get_drvdata(dev
);
78 error
= gp2a_enable(dt
);
80 dev_err(&dt
->i2c_client
->dev
,
81 "unable to activate, err %d\n", error
);
90 static void gp2a_device_close(struct input_dev
*dev
)
92 struct gp2a_data
*dt
= input_get_drvdata(dev
);
95 error
= gp2a_disable(dt
);
97 dev_err(&dt
->i2c_client
->dev
,
98 "unable to deactivate, err %d\n", error
);
101 static int gp2a_initialize(struct gp2a_data
*dt
)
105 error
= i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_GAIN
,
110 error
= i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_HYS
,
115 error
= i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_CYCLE
,
120 error
= gp2a_disable(dt
);
125 static int gp2a_probe(struct i2c_client
*client
,
126 const struct i2c_device_id
*id
)
128 const struct gp2a_platform_data
*pdata
= dev_get_platdata(&client
->dev
);
129 struct gp2a_data
*dt
;
135 if (pdata
->hw_setup
) {
136 error
= pdata
->hw_setup(client
);
141 error
= gpio_request_one(pdata
->vout_gpio
, GPIOF_IN
, GP2A_I2C_NAME
);
143 goto err_hw_shutdown
;
145 dt
= kzalloc(sizeof(struct gp2a_data
), GFP_KERNEL
);
152 dt
->i2c_client
= client
;
154 error
= gp2a_initialize(dt
);
158 dt
->input
= input_allocate_device();
164 input_set_drvdata(dt
->input
, dt
);
166 dt
->input
->open
= gp2a_device_open
;
167 dt
->input
->close
= gp2a_device_close
;
168 dt
->input
->name
= GP2A_I2C_NAME
;
169 dt
->input
->id
.bustype
= BUS_I2C
;
170 dt
->input
->dev
.parent
= &client
->dev
;
172 input_set_capability(dt
->input
, EV_SW
, SW_FRONT_PROXIMITY
);
174 error
= request_threaded_irq(client
->irq
, NULL
, gp2a_irq
,
175 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
|
179 dev_err(&client
->dev
, "irq request failed\n");
180 goto err_free_input_dev
;
183 error
= input_register_device(dt
->input
);
185 dev_err(&client
->dev
, "device registration failed\n");
189 device_init_wakeup(&client
->dev
, pdata
->wakeup
);
190 i2c_set_clientdata(client
, dt
);
195 free_irq(client
->irq
, dt
);
197 input_free_device(dt
->input
);
201 gpio_free(pdata
->vout_gpio
);
203 if (pdata
->hw_shutdown
)
204 pdata
->hw_shutdown(client
);
208 static int gp2a_remove(struct i2c_client
*client
)
210 struct gp2a_data
*dt
= i2c_get_clientdata(client
);
211 const struct gp2a_platform_data
*pdata
= dt
->pdata
;
213 free_irq(client
->irq
, dt
);
215 input_unregister_device(dt
->input
);
218 gpio_free(pdata
->vout_gpio
);
220 if (pdata
->hw_shutdown
)
221 pdata
->hw_shutdown(client
);
226 static int __maybe_unused
gp2a_suspend(struct device
*dev
)
228 struct i2c_client
*client
= to_i2c_client(dev
);
229 struct gp2a_data
*dt
= i2c_get_clientdata(client
);
232 if (device_may_wakeup(&client
->dev
)) {
233 enable_irq_wake(client
->irq
);
235 mutex_lock(&dt
->input
->mutex
);
236 if (dt
->input
->users
)
237 retval
= gp2a_disable(dt
);
238 mutex_unlock(&dt
->input
->mutex
);
244 static int __maybe_unused
gp2a_resume(struct device
*dev
)
246 struct i2c_client
*client
= to_i2c_client(dev
);
247 struct gp2a_data
*dt
= i2c_get_clientdata(client
);
250 if (device_may_wakeup(&client
->dev
)) {
251 disable_irq_wake(client
->irq
);
253 mutex_lock(&dt
->input
->mutex
);
254 if (dt
->input
->users
)
255 retval
= gp2a_enable(dt
);
256 mutex_unlock(&dt
->input
->mutex
);
262 static SIMPLE_DEV_PM_OPS(gp2a_pm
, gp2a_suspend
, gp2a_resume
);
264 static const struct i2c_device_id gp2a_i2c_id
[] = {
265 { GP2A_I2C_NAME
, 0 },
268 MODULE_DEVICE_TABLE(i2c
, gp2a_i2c_id
);
270 static struct i2c_driver gp2a_i2c_driver
= {
272 .name
= GP2A_I2C_NAME
,
276 .remove
= gp2a_remove
,
277 .id_table
= gp2a_i2c_id
,
280 module_i2c_driver(gp2a_i2c_driver
);
282 MODULE_AUTHOR("Courtney Cavin <courtney.cavin@sonyericsson.com>");
283 MODULE_DESCRIPTION("Sharp GP2AP002A00F I2C Proximity/Opto sensor driver");
284 MODULE_LICENSE("GPL v2");