root/drivers/media/i2c/upd64031a.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_state
  2. upd64031a_read
  3. upd64031a_write
  4. upd64031a_s_frequency
  5. upd64031a_s_routing
  6. upd64031a_log_status
  7. upd64031a_g_register
  8. upd64031a_s_register
  9. upd64031a_probe
  10. upd64031a_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * upd64031A - NEC Electronics Ghost Reduction for NTSC in Japan
   4  *
   5  * 2003 by T.Adachi <tadachi@tadachi-net.com>
   6  * 2003 by Takeru KOMORIYA <komoriya@paken.org>
   7  * 2006 by Hans Verkuil <hverkuil@xs4all.nl>
   8  */
   9 
  10 
  11 #include <linux/module.h>
  12 #include <linux/kernel.h>
  13 #include <linux/i2c.h>
  14 #include <linux/videodev2.h>
  15 #include <linux/slab.h>
  16 #include <media/v4l2-device.h>
  17 #include <media/i2c/upd64031a.h>
  18 
  19 /* --------------------- read registers functions define -------------------- */
  20 
  21 /* bit masks */
  22 #define GR_MODE_MASK              0xc0
  23 #define DIRECT_3DYCS_CONNECT_MASK 0xc0
  24 #define SYNC_CIRCUIT_MASK         0xa0
  25 
  26 /* -------------------------------------------------------------------------- */
  27 
  28 MODULE_DESCRIPTION("uPD64031A driver");
  29 MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil");
  30 MODULE_LICENSE("GPL");
  31 
  32 static int debug;
  33 module_param(debug, int, 0644);
  34 
  35 MODULE_PARM_DESC(debug, "Debug level (0-1)");
  36 
  37 
  38 enum {
  39         R00 = 0, R01, R02, R03, R04,
  40         R05, R06, R07, R08, R09,
  41         R0A, R0B, R0C, R0D, R0E, R0F,
  42         /* unused registers
  43          R10, R11, R12, R13, R14,
  44          R15, R16, R17,
  45          */
  46         TOT_REGS
  47 };
  48 
  49 struct upd64031a_state {
  50         struct v4l2_subdev sd;
  51         u8 regs[TOT_REGS];
  52         u8 gr_mode;
  53         u8 direct_3dycs_connect;
  54         u8 ext_comp_sync;
  55         u8 ext_vert_sync;
  56 };
  57 
  58 static inline struct upd64031a_state *to_state(struct v4l2_subdev *sd)
  59 {
  60         return container_of(sd, struct upd64031a_state, sd);
  61 }
  62 
  63 static u8 upd64031a_init[] = {
  64         0x00, 0xb8, 0x48, 0xd2, 0xe6,
  65         0x03, 0x10, 0x0b, 0xaf, 0x7f,
  66         0x00, 0x00, 0x1d, 0x5e, 0x00,
  67         0xd0
  68 };
  69 
  70 /* ------------------------------------------------------------------------ */
  71 
  72 static u8 upd64031a_read(struct v4l2_subdev *sd, u8 reg)
  73 {
  74         struct i2c_client *client = v4l2_get_subdevdata(sd);
  75         u8 buf[2];
  76 
  77         if (reg >= sizeof(buf))
  78                 return 0xff;
  79         i2c_master_recv(client, buf, 2);
  80         return buf[reg];
  81 }
  82 
  83 /* ------------------------------------------------------------------------ */
  84 
  85 static void upd64031a_write(struct v4l2_subdev *sd, u8 reg, u8 val)
  86 {
  87         struct i2c_client *client = v4l2_get_subdevdata(sd);
  88         u8 buf[2];
  89 
  90         buf[0] = reg;
  91         buf[1] = val;
  92         v4l2_dbg(1, debug, sd, "write reg: %02X val: %02X\n", reg, val);
  93         if (i2c_master_send(client, buf, 2) != 2)
  94                 v4l2_err(sd, "I/O error write 0x%02x/0x%02x\n", reg, val);
  95 }
  96 
  97 /* ------------------------------------------------------------------------ */
  98 
  99 /* The input changed due to new input or channel changed */
 100 static int upd64031a_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequency *freq)
 101 {
 102         struct upd64031a_state *state = to_state(sd);
 103         u8 reg = state->regs[R00];
 104 
 105         v4l2_dbg(1, debug, sd, "changed input or channel\n");
 106         upd64031a_write(sd, R00, reg | 0x10);
 107         upd64031a_write(sd, R00, reg & ~0x10);
 108         return 0;
 109 }
 110 
 111 /* ------------------------------------------------------------------------ */
 112 
 113 static int upd64031a_s_routing(struct v4l2_subdev *sd,
 114                                u32 input, u32 output, u32 config)
 115 {
 116         struct upd64031a_state *state = to_state(sd);
 117         u8 r00, r05, r08;
 118 
 119         state->gr_mode = (input & 3) << 6;
 120         state->direct_3dycs_connect = (input & 0xc) << 4;
 121         state->ext_comp_sync =
 122                 (input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
 123         state->ext_vert_sync =
 124                 (input & UPD64031A_VERTICAL_EXTERNAL) << 2;
 125         r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
 126         r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
 127                 state->ext_comp_sync | state->ext_vert_sync;
 128         r08 = (state->regs[R08] & ~DIRECT_3DYCS_CONNECT_MASK) |
 129                 state->direct_3dycs_connect;
 130         upd64031a_write(sd, R00, r00);
 131         upd64031a_write(sd, R05, r05);
 132         upd64031a_write(sd, R08, r08);
 133         return upd64031a_s_frequency(sd, NULL);
 134 }
 135 
 136 static int upd64031a_log_status(struct v4l2_subdev *sd)
 137 {
 138         v4l2_info(sd, "Status: SA00=0x%02x SA01=0x%02x\n",
 139                         upd64031a_read(sd, 0), upd64031a_read(sd, 1));
 140         return 0;
 141 }
 142 
 143 #ifdef CONFIG_VIDEO_ADV_DEBUG
 144 static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 145 {
 146         reg->val = upd64031a_read(sd, reg->reg & 0xff);
 147         reg->size = 1;
 148         return 0;
 149 }
 150 
 151 static int upd64031a_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 152 {
 153         upd64031a_write(sd, reg->reg & 0xff, reg->val & 0xff);
 154         return 0;
 155 }
 156 #endif
 157 
 158 /* ----------------------------------------------------------------------- */
 159 
 160 static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
 161         .log_status = upd64031a_log_status,
 162 #ifdef CONFIG_VIDEO_ADV_DEBUG
 163         .g_register = upd64031a_g_register,
 164         .s_register = upd64031a_s_register,
 165 #endif
 166 };
 167 
 168 static const struct v4l2_subdev_tuner_ops upd64031a_tuner_ops = {
 169         .s_frequency = upd64031a_s_frequency,
 170 };
 171 
 172 static const struct v4l2_subdev_video_ops upd64031a_video_ops = {
 173         .s_routing = upd64031a_s_routing,
 174 };
 175 
 176 static const struct v4l2_subdev_ops upd64031a_ops = {
 177         .core = &upd64031a_core_ops,
 178         .tuner = &upd64031a_tuner_ops,
 179         .video = &upd64031a_video_ops,
 180 };
 181 
 182 /* ------------------------------------------------------------------------ */
 183 
 184 /* i2c implementation */
 185 
 186 static int upd64031a_probe(struct i2c_client *client,
 187                            const struct i2c_device_id *id)
 188 {
 189         struct upd64031a_state *state;
 190         struct v4l2_subdev *sd;
 191         int i;
 192 
 193         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 194                 return -EIO;
 195 
 196         v4l_info(client, "chip found @ 0x%x (%s)\n",
 197                         client->addr << 1, client->adapter->name);
 198 
 199         state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 200         if (state == NULL)
 201                 return -ENOMEM;
 202         sd = &state->sd;
 203         v4l2_i2c_subdev_init(sd, client, &upd64031a_ops);
 204         memcpy(state->regs, upd64031a_init, sizeof(state->regs));
 205         state->gr_mode = UPD64031A_GR_ON << 6;
 206         state->direct_3dycs_connect = UPD64031A_3DYCS_COMPOSITE << 4;
 207         state->ext_comp_sync = state->ext_vert_sync = 0;
 208         for (i = 0; i < TOT_REGS; i++)
 209                 upd64031a_write(sd, i, state->regs[i]);
 210         return 0;
 211 }
 212 
 213 static int upd64031a_remove(struct i2c_client *client)
 214 {
 215         struct v4l2_subdev *sd = i2c_get_clientdata(client);
 216 
 217         v4l2_device_unregister_subdev(sd);
 218         return 0;
 219 }
 220 
 221 /* ----------------------------------------------------------------------- */
 222 
 223 static const struct i2c_device_id upd64031a_id[] = {
 224         { "upd64031a", 0 },
 225         { }
 226 };
 227 MODULE_DEVICE_TABLE(i2c, upd64031a_id);
 228 
 229 static struct i2c_driver upd64031a_driver = {
 230         .driver = {
 231                 .name   = "upd64031a",
 232         },
 233         .probe          = upd64031a_probe,
 234         .remove         = upd64031a_remove,
 235         .id_table       = upd64031a_id,
 236 };
 237 
 238 module_i2c_driver(upd64031a_driver);

/* [<][>][^][v][top][bottom][index][help] */