diff options
author | Rajat Verma <rajat.verma@stericsson.com> | 2011-10-07 12:13:05 +0530 |
---|---|---|
committer | Rabin VINCENT <rabin.vincent@stericsson.com> | 2011-10-10 10:18:34 +0200 |
commit | ed5f682f3b9d55229ff372ca682a1943b0af7e4e (patch) | |
tree | 64403d35f9a11a23185e73fed0d7915dda047090 | |
parent | 6149195baccd2f5a2b9481677fbf0cbcfde3c3c1 (diff) |
ux500: camera_flash: add platform data for adp1653
board specific information such as enable_gpio
and interrupt line information should be obtained
using platform_data and not hardcoded inside the
driver itself.
ST-Ericsson Linux next: NA
ST-Ericsson ID: 361940
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I73a0f3e986bd3cbf19a0797190d514af9b84e3df
Signed-off-by: Rajat Verma <rajat.verma@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33282
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Reviewed-by: Rabin VINCENT <rabin.vincent@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-stuib.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-u8500uib.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.h | 3 | ||||
-rw-r--r-- | drivers/staging/camera_flash/adp1653.c | 163 | ||||
-rwxr-xr-x | include/linux/i2c/adp1653_plat.h | 24 |
5 files changed, 106 insertions, 112 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c index f9b30f27303..751a98a6d7e 100644 --- a/arch/arm/mach-ux500/board-mop500-stuib.c +++ b/arch/arm/mach-ux500/board-mop500-stuib.c @@ -13,6 +13,7 @@ #include <linux/lsm303dlh.h> #include <linux/l3g4200d.h> #include <linux/i2c.h> +#include <linux/i2c/adp1653_plat.h> #include <linux/input/matrix_keypad.h> #include <linux/input/lps001wp.h> #include <asm/mach-types.h> @@ -48,6 +49,10 @@ static struct lps001wp_prs_platform_data __initdata lps001wp_pdata = { .min_interval = 10, }; +static struct adp1653_platform_data __initdata adp1653_pdata_u8500_uib = { + .irq_no = CAMERA_FLASH_INT_PIN +}; + static struct i2c_board_info __initdata mop500_i2c2_devices[] = { { /* LSM303DLH Accelerometer */ @@ -69,6 +74,10 @@ static struct i2c_board_info __initdata mop500_i2c2_devices[] = { I2C_BOARD_INFO("lps001wp_prs_sysfs", 0x5C), .platform_data = &lps001wp_pdata, }, + { + I2C_BOARD_INFO("adp1653", 0x30), + .platform_data = &adp1653_pdata_u8500_uib + } }; /* @@ -302,10 +311,13 @@ void __init mop500_stuib_init(void) if (machine_is_hrefv60()) { tsc_plat_device.cs_pin = HREFV60_TOUCH_RST_GPIO; tsc_plat2_device.cs_pin = HREFV60_TOUCH_RST_GPIO; + adp1653_pdata_u8500_uib.enable_gpio = + HREFV60_CAMERA_FLASH_ENABLE; } else { tsc_plat_device.cs_pin = GPIO_BU21013_CS; tsc_plat2_device.cs_pin = GPIO_BU21013_CS; - + adp1653_pdata_u8500_uib.enable_gpio = + GPIO_CAMERA_FLASH_ENABLE; } mop500_uib_i2c_add(0, mop500_i2c0_devices_stuib, diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c index adb6a1a0a3b..9e1cafa8893 100644 --- a/arch/arm/mach-ux500/board-mop500-u8500uib.c +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c @@ -8,6 +8,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/i2c.h> +#include <linux/i2c/adp1653_plat.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/lsm303dlh.h> @@ -45,6 +46,11 @@ static struct l3g4200d_gyr_platform_data __initdata l3g4200d_pdata_u8500 = { .negative_y = 0, .negative_z = 1, }; + +static struct adp1653_platform_data __initdata adp1653_pdata_u8500_uib = { + .irq_no = CAMERA_FLASH_INT_PIN +}; + static struct i2c_board_info __initdata mop500_i2c2_devices_u8500[] = { { /* LSM303DLH Accelerometer */ @@ -61,6 +67,10 @@ static struct i2c_board_info __initdata mop500_i2c2_devices_u8500[] = { I2C_BOARD_INFO("l3g4200d", 0x68), .platform_data = &l3g4200d_pdata_u8500, }, + { + I2C_BOARD_INFO("adp1653", 0x30), + .platform_data = &adp1653_pdata_u8500_uib + } }; /* @@ -155,10 +165,14 @@ void __init mop500_u8500uib_init(void) lsm303dlh_pdata_u8500.irq_a1 = HREFV60_ACCEL_INT1_GPIO; lsm303dlh_pdata_u8500.irq_a2 = HREFV60_ACCEL_INT2_GPIO; lsm303dlh_pdata_u8500.irq_m = HREFV60_MAGNET_DRDY_GPIO; + adp1653_pdata_u8500_uib.enable_gpio = + HREFV60_CAMERA_FLASH_ENABLE; } else { lsm303dlh_pdata_u8500.irq_a1 = GPIO_ACCEL_INT1; lsm303dlh_pdata_u8500.irq_a2 = GPIO_ACCEL_INT2; lsm303dlh_pdata_u8500.irq_m = GPIO_MAGNET_DRDY; + adp1653_pdata_u8500_uib.enable_gpio = + GPIO_CAMERA_FLASH_ENABLE; } mop500_uib_i2c_add(2, mop500_i2c2_devices_u8500, diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 273aa24b57e..80f241f79ce 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -35,8 +35,10 @@ #define HREFV60_DISP2_RST_GPIO 66 #define HREFV60_MMIO_XENON_CHARGE 170 #define HREFV60_XSHUTDOWN_SECONDARY_SENSOR 140 +#define HREFV60_CAMERA_FLASH_ENABLE 22 #define XSHUTDOWN_PRIMARY_SENSOR 141 #define XSHUTDOWN_SECONDARY_SENSOR 142 +#define CAMERA_FLASH_INT_PIN 7 #define CYPRESS_TOUCH_INT_PIN 84 #define CYPRESS_TOUCH_RST_GPIO 143 #define CYPRESS_SLAVE_SELECT_GPIO 216 @@ -46,6 +48,7 @@ /* GPIOs on the TC35892 expander */ #define GPIO_MAGNET_DRDY MOP500_EGPIO(1) #define GPIO_SDMMC_CD MOP500_EGPIO(3) +#define GPIO_CAMERA_FLASH_ENABLE MOP500_EGPIO(4) #define GPIO_MMIO_XENON_CHARGE MOP500_EGPIO(5) #define GPIO_PROX_SENSOR MOP500_EGPIO(7) #define GPIO_HAL_SENSOR MOP500_EGPIO(8) diff --git a/drivers/staging/camera_flash/adp1653.c b/drivers/staging/camera_flash/adp1653.c index b3ff662037f..81280cd4a18 100644 --- a/drivers/staging/camera_flash/adp1653.c +++ b/drivers/staging/camera_flash/adp1653.c @@ -10,6 +10,7 @@ #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/i2c.h> +#include <linux/i2c/adp1653_plat.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/version.h> @@ -20,22 +21,11 @@ /* This data is platform specific for 8500 href-v1 platform, * Ideally this should be supplied from platform code */ -//#define ADAPTER_I2C2 (2) -#define STR_GPIO (6) -static int strobe_gpio = 0; //TODO: set to 0 when it works static int adapter_i2c2 = 2; -static int flash_irq = 7; -static int enable_gpio = 272; static int flash_position = 0; -module_param(strobe_gpio, int, S_IRUGO); -MODULE_PARM_DESC(strobe_gpio, "use GPIO 6 to strobe, 0 means that someone else (sensor?) will strobe for us"); module_param(adapter_i2c2, int, S_IRUGO); MODULE_PARM_DESC(adapter_i2c2, "use the given I2C adaptater to communicate with the chip"); -module_param(flash_irq, int, S_IRUGO); -MODULE_PARM_DESC(flash_irq, "the GPIO number associated to the i2c irq line"); -module_param(enable_gpio, int, S_IRUGO); -MODULE_PARM_DESC(enable_gpio, "use the given GPIO line to enable the chip"); module_param(flash_position, int, S_IRUGO); MODULE_PARM_DESC(flash_position, "the position of the flash chip (0=PRIMARY, 1=SECONDARY)"); @@ -250,11 +240,6 @@ static int adp1653_strobe_still_led(struct adp1653_priv_data *priv_p,int enable) goto out; } - if (strobe_gpio != 0 ) - { - gpio_set_value(priv_p->strobe_gpio,gpio_val); - } - out: return err; } @@ -393,9 +378,10 @@ static irqreturn_t adp1653_irq_hdlr(int irq_no,void *data) static int __devinit adp1653_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int err=0; + int err = 0; struct flash_chip *flash_chip_p=NULL; struct adp1653_priv_data *priv_p=NULL; + struct adp1653_platform_data *pdata = client->dev.platform_data; DEBUG_LOG("> adp1653_probe\n"); @@ -403,15 +389,23 @@ static int __devinit adp1653_probe(struct i2c_client *client, if(!priv_p){ DEBUG_LOG("Kmalloc failed for priv data\n"); err = ENOMEM; - goto out; + goto err_priv; } priv_p->i2c_client = client; flash_chip_p = kzalloc(sizeof(struct flash_chip),GFP_KERNEL); if(!flash_chip_p){ DEBUG_LOG("Kmalloc failed for flash_chip_p"); err = ENOMEM; - goto out; + goto err_flash_chip_alloc; } + + if (!pdata) { + dev_err(&client->dev, + "%s: No platform data supplied.\n", __func__); + err = -EINVAL; + goto err_pdata; + } + flash_chip_p->priv_data = priv_p; flash_chip_p->ops = &adp1653_ops; SET_FLASHCHIP_TYPE(flash_chip_p,FLASH_TYPE_HPLED); @@ -422,98 +416,53 @@ static int __devinit adp1653_probe(struct i2c_client *client, i2c_set_clientdata(client,priv_p); /*Request GPIO and Register IRQ if supported by platform and flash chip*/ - if(machine_is_hrefv60()) - enable_gpio = 21; - else - enable_gpio = 272; - - if(enable_gpio){ - err = gpio_request(enable_gpio,"Camera LED flash Enable"); - if(err){ - DEBUG_LOG("Unable to get GPIO %d, for enable\n",enable_gpio); - goto out; - } - priv_p->enable_gpio = enable_gpio; - - err = gpio_direction_output(priv_p->enable_gpio, 1); - if(err){ - DEBUG_LOG("Unable to set GPIO %lu in output mode, err %d\n",priv_p->enable_gpio,err); - gpio_free(priv_p->enable_gpio); - goto out; - } - gpio_set_value(priv_p->enable_gpio, 1); + err = gpio_request(pdata->enable_gpio,"Camera LED flash Enable"); + if(err){ + DEBUG_LOG("Unable to get GPIO %d, for enable\n",pdata->enable_gpio); + goto err_pdata; } - if (strobe_gpio != 0) - { - err = gpio_request(STR_GPIO,"Camera flash strobe\n"); - if(err){ - DEBUG_LOG("Unable to request strobe GPIO\n"); - // somebody else requested this gpio ... - //goto out; - } - - err = gpio_direction_output(STR_GPIO, 0); - if(err){ - DEBUG_LOG("Unable to set GPIO %d in output mode, err %d\n",STR_GPIO,err); - goto out; - } + err = gpio_direction_output(pdata->enable_gpio, 1); + if(err){ + DEBUG_LOG("Unable to set GPIO %u in output mode, err %d\n",pdata->enable_gpio,err); + gpio_free(pdata->enable_gpio); + goto err_gpio_set; } - else - { - err = gpio_request(STR_GPIO,"Camera flash strobe\n"); - if(err){ - DEBUG_LOG("Unable to request strobe GPIO\n"); - // somebody else requested this gpio ... - //goto out; - } - - err = gpio_direction_input(STR_GPIO); - if(err){ - DEBUG_LOG("Unable to set GPIO %d in input mode, err %d\n",STR_GPIO,err); - goto out; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) - err = nmk_gpio_set_pull(STR_GPIO, NMK_GPIO_PULL_DOWN); -#endif - if(err){ - DEBUG_LOG("Unable to set pull down on GPIO %d\n",STR_GPIO); - goto out; - } + gpio_set_value_cansleep(pdata->enable_gpio, 1); + err = request_threaded_irq(gpio_to_irq(pdata->irq_no),NULL,adp1653_irq_hdlr, + IRQF_ONESHOT|IRQF_TRIGGER_FALLING, + "Adp1653 flash",priv_p); + if(err){ + DEBUG_LOG("Unable to register flash IRQ handler, irq %d, err %d\n", + pdata->irq_no,err); + goto err_irq; } - priv_p->strobe_gpio = STR_GPIO; - - if(client->irq){ - err = request_threaded_irq(client->irq,NULL,adp1653_irq_hdlr, - IRQF_ONESHOT|IRQF_TRIGGER_FALLING, - "Adp1653 flash",priv_p); - if(err){ - DEBUG_LOG("Unable to register flash IRQ handler, irq %d, err %d\n", - client->irq,err); - goto out; - } - } err = register_flash_chip(flash_position,flash_chip_p); if(err){ DEBUG_LOG("Failed to register Adp1653 as flash for %s camera\n", (flash_position?"Primary":"Secondary")); - goto out; + goto err_register; } SET_FLASH_STATUS(priv_p->status,FLASH_STATUS_READY); DEBUG_LOG("< adp1653_probe ok\n"); return err; -out: - if(priv_p->irq_no) - free_irq(priv_p->irq_no,NULL); - if(priv_p->enable_gpio) - gpio_free(priv_p->enable_gpio); - if(priv_p) - kfree(priv_p); +err_register: + if(pdata->irq_no) + free_irq(pdata->irq_no,NULL); +err_irq: + gpio_set_value_cansleep(pdata->enable_gpio, 0); +err_gpio_set: + if(pdata->enable_gpio) + gpio_free(pdata->enable_gpio); +err_pdata: if(flash_chip_p) kfree(flash_chip_p); +err_flash_chip_alloc: + if(priv_p) + kfree(priv_p); +err_priv: DEBUG_LOG("< adp1653_probe (%d)\n", err); return err; } @@ -539,16 +488,15 @@ static struct i2c_driver adp1653_i2c_driver = { }; int adp1653_init(void){ - int err=0; + int err = 0; struct i2c_adapter *adap_p; struct i2c_board_info info; - /*Registration of I2C flash device is platform specific code - *Ideally it should be done from kernel (arch/arm/mach-XXX). - *Do it locally till the time it gets into platform code - *OR This portion (registration of device) and flash chip init - *Routine can be moved to Flash chip module init. - */ + /* Registration of I2C flash device is platform specific code + * Ideally it should be done from kernel (arch/arm/mach-XXX). + * Do it locally till the time it gets into platform code + * OR This portion (registration of device) and flash chip init + * Routine can be moved to Flash chip module init. */ DEBUG_LOG("getting I2C adaptor %d\n",adapter_i2c2); adap_p = i2c_get_adapter(adapter_i2c2); if(!adap_p){ @@ -557,21 +505,16 @@ int adp1653_init(void){ } memset(&info,0,sizeof( struct i2c_board_info)); - info.irq = __flash_gpio_to_irq(flash_irq); - strcpy(&info.type[0],"adp1653"); - DEBUG_LOG("trying to register %s at position %d, GPIO enable %d, GPIO IRQ line %d\n", + DEBUG_LOG("trying to register %s at position %d\n", info.type, - flash_position, - enable_gpio, - flash_irq); + flash_position); /* I2C framework expects least significant 7 bits as address, not complete * 8 bits with bit 0 (read/write bit) */ info.addr = 0x60 >> 1; - err = i2c_add_driver(&adp1653_i2c_driver); if(err) { @@ -579,13 +522,11 @@ int adp1653_init(void){ goto out; } - DEBUG_LOG("Initialized adp1653\n"); if(!i2c_new_device(adap_p,&info)){ DEBUG_LOG("Unable to add i2c dev: %s (err=%d)\n",info.type, err); goto out; } - out: return err; } diff --git a/include/linux/i2c/adp1653_plat.h b/include/linux/i2c/adp1653_plat.h new file mode 100755 index 00000000000..325097aa2a8 --- /dev/null +++ b/include/linux/i2c/adp1653_plat.h @@ -0,0 +1,24 @@ +/* + * adp1653_plat.h + * ADP1653 Led Flash Driver platform specific structures + * + * Copyright (C) ST-Ericsson SA 2011 + * Author: Rajat Verma <rajat.verma@stericsson.com> + * + * License Terms: GNU General Public License v2 + */ + +#ifndef __LINUX_I2C_ADP1653_PLAT_H__ +#define __LINUX_I2C_ADP1653_PLAT_H__ + +/** + * struct adp1653_platform_data - platform data structure for adp1653 + * @enable_gpio: gpio for chip enable/disable + * @irq_no: interrupt line for flash ic + */ +struct adp1653_platform_data { + u32 enable_gpio; + u32 irq_no; +}; + +#endif //__LINUX_I2C_ADP1653_PLAT_H__ |