diff options
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_phyflex.c | 48 | ||||
-rw-r--r-- | drivers/media/video/tw9910.c | 10 | ||||
-rw-r--r-- | include/media/tw9910.h | 1 |
3 files changed, 58 insertions, 1 deletions
diff --git a/arch/arm/mach-mx6/board-mx6q_phyflex.c b/arch/arm/mach-mx6/board-mx6q_phyflex.c index b98344145981..43d7973c7891 100644 --- a/arch/arm/mach-mx6/board-mx6q_phyflex.c +++ b/arch/arm/mach-mx6/board-mx6q_phyflex.c @@ -33,6 +33,7 @@ #include <linux/spi/flash.h> #include <linux/i2c.h> #include <linux/i2c/at24.h> +#include <linux/i2c/pca953x.h> #include <linux/leds-pca9532.h> #include <linux/ata.h> #include <linux/mtd/mtd.h> @@ -138,7 +139,7 @@ // #define MX6_PHYFLEX_CAN2_EN IMX_GPIO_NR(5, 24) #define MX6_PHYFLEX_CSI0_RST_TVIN IMX_GPIO_NR(5, 25) #define MX6_PHYFLEX_MAX7310_1_BASE_ADDR IMX_GPIO_NR(8, 0) -#define MX6_PHYFLEX_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8) +#define MX6_PHYFLEX_PCA9538_BASE_ADDR IMX_GPIO_NR(8, 8) // #define MX6_PHYFLEX_IO_EXP_GPIO1(x) (MX6_PHYFLEX_MAX7310_1_BASE_ADDR + (x)) // #define MX6_PHYFLEX_IO_EXP_GPIO2(x) (MX6_PHYFLEX_MAX7310_2_BASE_ADDR + (x)) @@ -364,6 +365,26 @@ static struct edt_ft5x06_platform_data mx6_phyflex_ft5x06_data = { .reset_pin = -1, /* static high */ }; +static int pca9538_setup(struct i2c_client *client, + unsigned gpio_base, unsigned ngpio, + void *context) +{ + int n; + + for (n = 0; n < ngpio; ++n) { + gpio_request(gpio_base + n, "PCA9538 GPIO Expander"); + gpio_direction_output(gpio_base + n, 1); + } + + return 0; +} + +static struct pca953x_platform_data pca9538_platdata = { + .gpio_base = MX6_PHYFLEX_PCA9538_BASE_ADDR, + .invert = 0, + .setup = pca9538_setup, +}; + static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { { I2C_BOARD_INFO("max7300", 0x40), @@ -402,6 +423,9 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { I2C_BOARD_INFO("stmpe811", 0x41), .irq = gpio_to_irq(MX6_PHYFLEX_CAP_TCH_INT1), .platform_data = (void *)&stmpe811_data1, + }, { + I2C_BOARD_INFO("pca9538", 0x70), + .platform_data = &pca9538_platdata, } }; @@ -1050,7 +1074,29 @@ static struct i2c_board_info phyflex_cameras[] = { #define SOC_CAM_LINK(bus, bi, i2c_adapter) \ .bus_id = bus, .board_info = bi, .i2c_adapter_id = i2c_adapter +int tw9910_switch_input(int input) +{ + int i; + + for (i = 0; i < 4; i++) { + if (i == input) { + gpio_direction_output(MX6_PHYFLEX_PCA9538_BASE_ADDR + + i * 2, 0); + gpio_direction_output(MX6_PHYFLEX_PCA9538_BASE_ADDR + + i * 2 + 1, 0); + } else { + gpio_direction_output(MX6_PHYFLEX_PCA9538_BASE_ADDR + + i * 2, 1); + gpio_direction_output(MX6_PHYFLEX_PCA9538_BASE_ADDR + + i * 2 + 1, 1); + } + } + + return 0; +} + struct tw9910_video_info tw9910_info = { + .switch_input = tw9910_switch_input, .buswidth = SOCAM_DATAWIDTH_8, .mpout = TW9910_MPO_RTCO, }; diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 9108de02881b..4b5528dd7ea9 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -925,10 +925,14 @@ static int tw9910_g_input(struct soc_camera_device *icd, unsigned int *i) static int tw9910_s_input(struct soc_camera_device *icd, unsigned int i) { struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct tw9910_priv *priv = to_tw9910(client); if (tw9910_mask_set(client, INFORM, 0X0C, i << 2)) return -EINVAL; + if (priv->info->switch_input) + priv->info->switch_input(i); + return 0; } @@ -989,6 +993,7 @@ static int tw9910_probe(struct i2c_client *client, struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct soc_camera_link *icl; + int input; int ret; if (!icd) { @@ -1026,6 +1031,11 @@ static int tw9910_probe(struct i2c_client *client, kfree(priv); } + input = (i2c_smbus_read_byte_data(client, INFORM) & 0x0C) >> 2; + + if (priv->info->switch_input) + priv->info->switch_input(input); + return ret; } diff --git a/include/media/tw9910.h b/include/media/tw9910.h index 90bcf1fa5421..7c800e24d7df 100644 --- a/include/media/tw9910.h +++ b/include/media/tw9910.h @@ -30,6 +30,7 @@ enum tw9910_mpout_pin { }; struct tw9910_video_info { + int (*switch_input)(int input); unsigned long buswidth; enum tw9910_mpout_pin mpout; }; |