summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Lavnikevich <d.lavnikevich@sam-solutions.net>2013-05-13 17:21:10 +0300
committerJustin Waters <justin.waters@timesys.com>2013-11-07 12:19:31 -0500
commitb6b0a0682e4503a3c4dded8bd835024ece15ff28 (patch)
tree527f7cd4c6927ebd25d6f2160fa7d0dd215a4ca0
parent24500e2e4bff773d1ca822ca3af2730e5d7f62cb (diff)
Implemented video capture board led control.
For led control pca9538 is used. Currently both green and red leds are on for selected video input. Signed-off-by: Uladzimir Bely <u.bely@sam-solutions.net> Signed-off-by: Christian Hemp <c.hemp@phytec.de>
-rw-r--r--arch/arm/mach-mx6/board-mx6q_phyflex.c48
-rw-r--r--drivers/media/video/tw9910.c10
-rw-r--r--include/media/tw9910.h1
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;
};