@@ -201,12 +201,6 @@
/*
* structure
*/
-
-struct regval_list {
- unsigned char reg_num;
- unsigned char value;
-};
-
struct tw9910_scale_ctrl {
char *name;
unsigned short width;
@@ -229,18 +223,6 @@ struct tw9910_priv {
int rev;
};
-/*
- * register settings
- */
-
-#define ENDMARKER { 0xff, 0xff }
-
-static const struct regval_list tw9910_default_regs[] =
-{
- { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC },
- ENDMARKER,
-};
-
static const struct soc_camera_data_format tw9910_color_fmt[] = {
{
.name = "VYUY",
@@ -442,20 +424,6 @@ static int tw9910_set_hsync(struct i2c_client *client,
return ret;
}
-static int tw9910_write_array(struct i2c_client *client,
- const struct regval_list *vals)
-{
- while (vals->reg_num != 0xff) {
- int ret = i2c_smbus_write_byte_data(client,
- vals->reg_num,
- vals->value);
- if (ret < 0)
- return ret;
- vals++;
- }
- return 0;
-}
-
static int tw9910_mask_set(struct i2c_client *client, u8 command,
u8 mask, u8 set)
{
@@ -469,6 +437,24 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command,
return i2c_smbus_write_byte_data(client, command, val);
}
+static int tw9910_set_outputcontrol(struct i2c_client *client)
+{
+ struct tw9910_priv *priv = to_tw9910(client);
+ u32 flags = priv->info->flags;
+ u8 val = 0;
+
+ if (flags & TW9910_FLG_VS_ACTIVE_HIGH)
+ val |= (1 << 7);
+
+ if (flags & TW9910_FLG_HS_ACTIVE_HIGH)
+ val |= (1 << 3);
+
+ val |= ((flags & TW9910_FLG_VS_MASK) >> TW9910_FLG_VS_SHIFT) << 4;
+ val |= ((flags & TW9910_FLG_HS_MASK) >> TW9910_FLG_HS_SHIFT) << 0;
+
+ return tw9910_mask_set(client, OUTCTR1, 0xff, val);
+}
+
static void tw9910_reset(struct i2c_client *client)
{
i2c_smbus_write_byte_data(client, ACNTL1, SRESET);
@@ -513,7 +499,7 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
{
struct i2c_client *client = sd->priv;
struct tw9910_priv *priv = to_tw9910(client);
- u8 val;
+ u8 val = OEN;
if (!enable) {
switch (priv->rev) {
@@ -556,7 +542,12 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
struct soc_camera_link *icl = to_soc_camera_link(icd);
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
- SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
+ SOCAM_DATA_ACTIVE_HIGH;
+
+ if (TW9910_FLG_DATAWIDTH_16 & priv->info->flags)
+ flags |= SOCAM_DATAWIDTH_16;
+ else
+ flags |= SOCAM_DATAWIDTH_8;
return soc_camera_apply_sensor_flags(icl, flags);
}
@@ -648,7 +639,7 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
* reset hardware
*/
tw9910_reset(client);
- ret = tw9910_write_array(client, tw9910_default_regs);
+ ret = tw9910_set_outputcontrol(client);
if (ret < 0)
goto tw9910_set_fmt_error;
@@ -656,7 +647,7 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
* set bus width
*/
val = 0x00;
- if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
+ if (TW9910_FLG_DATAWIDTH_16 & priv->info->flags)
val = LEN;
ret = tw9910_mask_set(client, OPFORM, LEN, val);
@@ -888,15 +879,6 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
return -ENODEV;
- /*
- * tw9910 only use 8 or 16 bit bus width
- */
- if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
- SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
- dev_err(&client->dev, "bus width error\n");
- return -ENODEV;
- }
-
icd->formats = tw9910_color_fmt;
icd->num_formats = ARRAY_SIZE(tw9910_color_fmt);
@@ -18,6 +18,25 @@
#include <media/soc_camera.h>
+#define TW9910_FLG_DATAWIDTH_16 (1 << 0) /* default 8 */
+#define TW9910_FLG_VS_ACTIVE_HIGH (1 << 1) /* default Low */
+#define TW9910_FLG_HS_ACTIVE_HIGH (1 << 2) /* default Low */
+
+#define TW9910_FLG_VS_SHIFT (4)
+#define TW9910_FLG_VS_MASK (0xF << TW9910_FLG_VS_SHIFT)
+#define TW9910_FLG_VS_VSYNC (0 << TW9910_FLG_VS_SHIFT)
+#define TW9910_FLG_VS_VACT (1 << TW9910_FLG_VS_SHIFT)
+#define TW9910_FLG_VS_FIELD (2 << TW9910_FLG_VS_SHIFT)
+#define TW9910_FLG_VS_VVALID (3 << TW9910_FLG_VS_SHIFT)
+
+#define TW9910_FLG_HS_SHIFT (8)
+#define TW9910_FLG_HS_MASK (0xF << TW9910_FLG_HS_SHIFT)
+#define TW9910_FLG_HS_HACT (0 << TW9910_FLG_HS_SHIFT)
+#define TW9910_FLG_HS_HSYNC (1 << TW9910_FLG_HS_SHIFT)
+#define TW9910_FLG_HS_DVALID (2 << TW9910_FLG_HS_SHIFT)
+#define TW9910_FLG_HS_HLOCK (3 << TW9910_FLG_HS_SHIFT)
+#define TW9910_FLG_HS_ASYNCW (4 << TW9910_FLG_HS_SHIFT)
+
enum tw9910_mpout_pin {
TW9910_MPO_VLOSS,
TW9910_MPO_HLOCK,
@@ -30,7 +49,7 @@ enum tw9910_mpout_pin {
};
struct tw9910_video_info {
- unsigned long buswidth;
+ u32 flags;
enum tw9910_mpout_pin mpout;
struct soc_camera_link link;
u16 start_offset;