Commit ee4b9dbb83c73c5408d7f479a501551a63ec57d3

Authored by Richard Röjfors
Committed by Mauro Carvalho Chehab
1 parent 08c45cd585

V4L/DVB: radio: add support for SAA7706H Car Radio DSP

Initial support for the SAA7706H Car Radio DSP.

It is a I2C device and currently the mute control is supported.

When the device is unmuted it is brought out of reset and initiated using
the proposed intialisation sequence.

When muted the DSP is brought into reset state.

[akpm@linux-foundation.org: include delay.h]

Signed-off-by: Richard Röjfors <richard.rojfors@pelagicore.com>
Cc: Douglas Schilling Landgraf <dougsland@gmail.com>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 4 changed files with 467 additions and 0 deletions Side-by-side Diff

drivers/media/radio/Kconfig
... ... @@ -417,6 +417,18 @@
417 417 Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
418 418 here if TEA5764 reference frequency is connected in FREQIN.
419 419  
  420 +config RADIO_SAA7706H
  421 + tristate "SAA7706H Car Radio DSP"
  422 + depends on I2C && VIDEO_V4L2
  423 + ---help---
  424 + Say Y here if you want to use the SAA7706H Car radio Digital
  425 + Signal Processor, found for instance on the Russellville development
  426 + board. On the russellville the device is connected to internal
  427 + timberdale I2C bus.
  428 +
  429 + To compile this driver as a module, choose M here: the
  430 + module will be called SAA7706H.
  431 +
420 432 config RADIO_TEF6862
421 433 tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
422 434 depends on I2C && VIDEO_V4L2
drivers/media/radio/Makefile
... ... @@ -23,6 +23,7 @@
23 23 obj-$(CONFIG_RADIO_SI470X) += si470x/
24 24 obj-$(CONFIG_USB_MR800) += radio-mr800.o
25 25 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
  26 +obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
26 27 obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
27 28  
28 29 EXTRA_CFLAGS += -Isound
drivers/media/radio/saa7706h.c
  1 +/*
  2 + * saa7706.c Philips SAA7706H Car Radio DSP driver
  3 + * Copyright (c) 2009 Intel Corporation
  4 + *
  5 + * This program is free software; you can redistribute it and/or modify
  6 + * it under the terms of the GNU General Public License version 2 as
  7 + * published by the Free Software Foundation.
  8 + *
  9 + * This program is distributed in the hope that it will be useful,
  10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 + * GNU General Public License for more details.
  13 + *
  14 + * You should have received a copy of the GNU General Public License
  15 + * along with this program; if not, write to the Free Software
  16 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17 + */
  18 +
  19 +#include <linux/module.h>
  20 +#include <linux/init.h>
  21 +#include <linux/delay.h>
  22 +#include <linux/errno.h>
  23 +#include <linux/kernel.h>
  24 +#include <linux/interrupt.h>
  25 +#include <linux/i2c.h>
  26 +#include <media/v4l2-device.h>
  27 +#include <media/v4l2-chip-ident.h>
  28 +
  29 +#define DRIVER_NAME "saa7706h"
  30 +
  31 +/* the I2C memory map looks like this
  32 +
  33 + $1C00 - $FFFF Not Used
  34 + $2200 - $3FFF Reserved YRAM (DSP2) space
  35 + $2000 - $21FF YRAM (DSP2)
  36 + $1FF0 - $1FFF Hardware Registers
  37 + $1280 - $1FEF Reserved XRAM (DSP2) space
  38 + $1000 - $127F XRAM (DSP2)
  39 + $0FFF DSP CONTROL
  40 + $0A00 - $0FFE Reserved
  41 + $0980 - $09FF Reserved YRAM (DSP1) space
  42 + $0800 - $097F YRAM (DSP1)
  43 + $0200 - $07FF Not Used
  44 + $0180 - $01FF Reserved XRAM (DSP1) space
  45 + $0000 - $017F XRAM (DSP1)
  46 +*/
  47 +
  48 +#define SAA7706H_REG_CTRL 0x0fff
  49 +#define SAA7706H_CTRL_BYP_PLL 0x0001
  50 +#define SAA7706H_CTRL_PLL_DIV_MASK 0x003e
  51 +#define SAA7706H_CTRL_PLL3_62975MHZ 0x003e
  52 +#define SAA7706H_CTRL_DSP_TURBO 0x0040
  53 +#define SAA7706H_CTRL_PC_RESET_DSP1 0x0080
  54 +#define SAA7706H_CTRL_PC_RESET_DSP2 0x0100
  55 +#define SAA7706H_CTRL_DSP1_ROM_EN_MASK 0x0600
  56 +#define SAA7706H_CTRL_DSP1_FUNC_PROM 0x0000
  57 +#define SAA7706H_CTRL_DSP2_ROM_EN_MASK 0x1800
  58 +#define SAA7706H_CTRL_DSP2_FUNC_PROM 0x0000
  59 +#define SAA7706H_CTRL_DIG_SIL_INTERPOL 0x8000
  60 +
  61 +#define SAA7706H_REG_EVALUATION 0x1ff0
  62 +#define SAA7706H_EVAL_DISABLE_CHARGE_PUMP 0x000001
  63 +#define SAA7706H_EVAL_DCS_CLOCK 0x000002
  64 +#define SAA7706H_EVAL_GNDRC1_ENABLE 0x000004
  65 +#define SAA7706H_EVAL_GNDRC2_ENABLE 0x000008
  66 +
  67 +#define SAA7706H_REG_CL_GEN1 0x1ff3
  68 +#define SAA7706H_CL_GEN1_MIN_LOOPGAIN_MASK 0x00000f
  69 +#define SAA7706H_CL_GEN1_LOOPGAIN_MASK 0x0000f0
  70 +#define SAA7706H_CL_GEN1_COARSE_RATION 0xffff00
  71 +
  72 +#define SAA7706H_REG_CL_GEN2 0x1ff4
  73 +#define SAA7706H_CL_GEN2_WSEDGE_FALLING 0x000001
  74 +#define SAA7706H_CL_GEN2_STOP_VCO 0x000002
  75 +#define SAA7706H_CL_GEN2_FRERUN 0x000004
  76 +#define SAA7706H_CL_GEN2_ADAPTIVE 0x000008
  77 +#define SAA7706H_CL_GEN2_FINE_RATIO_MASK 0x0ffff0
  78 +
  79 +#define SAA7706H_REG_CL_GEN4 0x1ff6
  80 +#define SAA7706H_CL_GEN4_BYPASS_PLL1 0x001000
  81 +#define SAA7706H_CL_GEN4_PLL1_DIV_MASK 0x03e000
  82 +#define SAA7706H_CL_GEN4_DSP1_TURBO 0x040000
  83 +
  84 +#define SAA7706H_REG_SEL 0x1ff7
  85 +#define SAA7706H_SEL_DSP2_SRCA_MASK 0x000007
  86 +#define SAA7706H_SEL_DSP2_FMTA_MASK 0x000031
  87 +#define SAA7706H_SEL_DSP2_SRCB_MASK 0x0001c0
  88 +#define SAA7706H_SEL_DSP2_FMTB_MASK 0x000e00
  89 +#define SAA7706H_SEL_DSP1_SRC_MASK 0x003000
  90 +#define SAA7706H_SEL_DSP1_FMT_MASK 0x01c003
  91 +#define SAA7706H_SEL_SPDIF2 0x020000
  92 +#define SAA7706H_SEL_HOST_IO_FMT_MASK 0x1c0000
  93 +#define SAA7706H_SEL_EN_HOST_IO 0x200000
  94 +
  95 +#define SAA7706H_REG_IAC 0x1ff8
  96 +#define SAA7706H_REG_CLK_SET 0x1ff9
  97 +#define SAA7706H_REG_CLK_COEFF 0x1ffa
  98 +#define SAA7706H_REG_INPUT_SENS 0x1ffb
  99 +#define SAA7706H_INPUT_SENS_RDS_VOL_MASK 0x0003f
  100 +#define SAA7706H_INPUT_SENS_FM_VOL_MASK 0x00fc0
  101 +#define SAA7706H_INPUT_SENS_FM_MPX 0x01000
  102 +#define SAA7706H_INPUT_SENS_OFF_FILTER_A_EN 0x02000
  103 +#define SAA7706H_INPUT_SENS_OFF_FILTER_B_EN 0x04000
  104 +#define SAA7706H_REG_PHONE_NAV_AUDIO 0x1ffc
  105 +#define SAA7706H_REG_IO_CONF_DSP2 0x1ffd
  106 +#define SAA7706H_REG_STATUS_DSP2 0x1ffe
  107 +#define SAA7706H_REG_PC_DSP2 0x1fff
  108 +
  109 +#define SAA7706H_DSP1_MOD0 0x0800
  110 +#define SAA7706H_DSP1_ROM_VER 0x097f
  111 +#define SAA7706H_DSP2_MPTR0 0x1000
  112 +
  113 +#define SAA7706H_DSP1_MODPNTR 0x0000
  114 +
  115 +#define SAA7706H_DSP2_XMEM_CONTLLCW 0x113e
  116 +#define SAA7706H_DSP2_XMEM_BUSAMP 0x114a
  117 +#define SAA7706H_DSP2_XMEM_FDACPNTR 0x11f9
  118 +#define SAA7706H_DSP2_XMEM_IIS1PNTR 0x11fb
  119 +
  120 +#define SAA7706H_DSP2_YMEM_PVGA 0x212a
  121 +#define SAA7706H_DSP2_YMEM_PVAT1 0x212b
  122 +#define SAA7706H_DSP2_YMEM_PVAT 0x212c
  123 +#define SAA7706H_DSP2_YMEM_ROM_VER 0x21ff
  124 +
  125 +#define SUPPORTED_DSP1_ROM_VER 0x667
  126 +
  127 +struct saa7706h_state {
  128 + struct v4l2_subdev sd;
  129 + unsigned muted;
  130 +};
  131 +
  132 +static inline struct saa7706h_state *to_state(struct v4l2_subdev *sd)
  133 +{
  134 + return container_of(sd, struct saa7706h_state, sd);
  135 +}
  136 +
  137 +static int saa7706h_i2c_send(struct i2c_client *client, const u8 *data, int len)
  138 +{
  139 + int err = i2c_master_send(client, data, len);
  140 + if (err == len)
  141 + return 0;
  142 + return err > 0 ? -EIO : err;
  143 +}
  144 +
  145 +static int saa7706h_i2c_transfer(struct i2c_client *client,
  146 + struct i2c_msg *msgs, int num)
  147 +{
  148 + int err = i2c_transfer(client->adapter, msgs, num);
  149 + if (err == num)
  150 + return 0;
  151 + return err > 0 ? -EIO : err;
  152 +}
  153 +
  154 +static int saa7706h_set_reg24(struct v4l2_subdev *sd, u16 reg, u32 val)
  155 +{
  156 + struct i2c_client *client = v4l2_get_subdevdata(sd);
  157 + u8 buf[5];
  158 + int pos = 0;
  159 +
  160 + buf[pos++] = reg >> 8;
  161 + buf[pos++] = reg;
  162 + buf[pos++] = val >> 16;
  163 + buf[pos++] = val >> 8;
  164 + buf[pos++] = val;
  165 +
  166 + return saa7706h_i2c_send(client, buf, pos);
  167 +}
  168 +
  169 +static int saa7706h_set_reg24_err(struct v4l2_subdev *sd, u16 reg, u32 val,
  170 + int *err)
  171 +{
  172 + return *err ? *err : saa7706h_set_reg24(sd, reg, val);
  173 +}
  174 +
  175 +static int saa7706h_set_reg16(struct v4l2_subdev *sd, u16 reg, u16 val)
  176 +{
  177 + struct i2c_client *client = v4l2_get_subdevdata(sd);
  178 + u8 buf[4];
  179 + int pos = 0;
  180 +
  181 + buf[pos++] = reg >> 8;
  182 + buf[pos++] = reg;
  183 + buf[pos++] = val >> 8;
  184 + buf[pos++] = val;
  185 +
  186 + return saa7706h_i2c_send(client, buf, pos);
  187 +}
  188 +
  189 +static int saa7706h_set_reg16_err(struct v4l2_subdev *sd, u16 reg, u16 val,
  190 + int *err)
  191 +{
  192 + return *err ? *err : saa7706h_set_reg16(sd, reg, val);
  193 +}
  194 +
  195 +static int saa7706h_get_reg16(struct v4l2_subdev *sd, u16 reg)
  196 +{
  197 + struct i2c_client *client = v4l2_get_subdevdata(sd);
  198 + u8 buf[2];
  199 + int err;
  200 + u8 regaddr[] = {reg >> 8, reg};
  201 + struct i2c_msg msg[] = { {client->addr, 0, sizeof(regaddr), regaddr},
  202 + {client->addr, I2C_M_RD, sizeof(buf), buf} };
  203 +
  204 + err = saa7706h_i2c_transfer(client, msg, ARRAY_SIZE(msg));
  205 + if (err)
  206 + return err;
  207 +
  208 + return buf[0] << 8 | buf[1];
  209 +}
  210 +
  211 +static int saa7706h_unmute(struct v4l2_subdev *sd)
  212 +{
  213 + struct saa7706h_state *state = to_state(sd);
  214 + int err = 0;
  215 +
  216 + err = saa7706h_set_reg16_err(sd, SAA7706H_REG_CTRL,
  217 + SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
  218 + SAA7706H_CTRL_PC_RESET_DSP2, &err);
  219 +
  220 + /* newer versions of the chip requires a small sleep after reset */
  221 + msleep(1);
  222 +
  223 + err = saa7706h_set_reg16_err(sd, SAA7706H_REG_CTRL,
  224 + SAA7706H_CTRL_PLL3_62975MHZ, &err);
  225 +
  226 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_EVALUATION, 0, &err);
  227 +
  228 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN1, 0x040022, &err);
  229 +
  230 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN2,
  231 + SAA7706H_CL_GEN2_WSEDGE_FALLING, &err);
  232 +
  233 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN4, 0x024080, &err);
  234 +
  235 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_SEL, 0x200080, &err);
  236 +
  237 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_IAC, 0xf4caed, &err);
  238 +
  239 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CLK_SET, 0x124334, &err);
  240 +
  241 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CLK_COEFF, 0x004a1a,
  242 + &err);
  243 +
  244 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_INPUT_SENS, 0x0071c7,
  245 + &err);
  246 +
  247 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_PHONE_NAV_AUDIO,
  248 + 0x0e22ff, &err);
  249 +
  250 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_IO_CONF_DSP2, 0x001ff8,
  251 + &err);
  252 +
  253 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_STATUS_DSP2, 0x080003,
  254 + &err);
  255 +
  256 + err = saa7706h_set_reg24_err(sd, SAA7706H_REG_PC_DSP2, 0x000004, &err);
  257 +
  258 + err = saa7706h_set_reg16_err(sd, SAA7706H_DSP1_MOD0, 0x0c6c, &err);
  259 +
  260 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_MPTR0, 0x000b4b, &err);
  261 +
  262 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP1_MODPNTR, 0x000600, &err);
  263 +
  264 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP1_MODPNTR, 0x0000c0, &err);
  265 +
  266 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000819,
  267 + &err);
  268 +
  269 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x00085a,
  270 + &err);
  271 +
  272 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_BUSAMP, 0x7fffff,
  273 + &err);
  274 +
  275 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_FDACPNTR, 0x2000cb,
  276 + &err);
  277 +
  278 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_IIS1PNTR, 0x2000cb,
  279 + &err);
  280 +
  281 + err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVGA, 0x0f80, &err);
  282 +
  283 + err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVAT1, 0x0800,
  284 + &err);
  285 +
  286 + err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVAT, 0x0800, &err);
  287 +
  288 + err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000905,
  289 + &err);
  290 + if (!err)
  291 + state->muted = 0;
  292 + return err;
  293 +}
  294 +
  295 +static int saa7706h_mute(struct v4l2_subdev *sd)
  296 +{
  297 + struct saa7706h_state *state = to_state(sd);
  298 + int err;
  299 +
  300 + err = saa7706h_set_reg16(sd, SAA7706H_REG_CTRL,
  301 + SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
  302 + SAA7706H_CTRL_PC_RESET_DSP2);
  303 + if (!err)
  304 + state->muted = 1;
  305 + return err;
  306 +}
  307 +
  308 +static int saa7706h_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
  309 +{
  310 + switch (qc->id) {
  311 + case V4L2_CID_AUDIO_MUTE:
  312 + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
  313 + }
  314 + return -EINVAL;
  315 +}
  316 +
  317 +static int saa7706h_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
  318 +{
  319 + struct saa7706h_state *state = to_state(sd);
  320 +
  321 + switch (ctrl->id) {
  322 + case V4L2_CID_AUDIO_MUTE:
  323 + ctrl->value = state->muted;
  324 + return 0;
  325 + }
  326 + return -EINVAL;
  327 +}
  328 +
  329 +static int saa7706h_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
  330 +{
  331 + switch (ctrl->id) {
  332 + case V4L2_CID_AUDIO_MUTE:
  333 + if (ctrl->value)
  334 + return saa7706h_mute(sd);
  335 + return saa7706h_unmute(sd);
  336 + }
  337 + return -EINVAL;
  338 +}
  339 +
  340 +static int saa7706h_g_chip_ident(struct v4l2_subdev *sd,
  341 + struct v4l2_dbg_chip_ident *chip)
  342 +{
  343 + struct i2c_client *client = v4l2_get_subdevdata(sd);
  344 +
  345 + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7706H, 0);
  346 +}
  347 +
  348 +static const struct v4l2_subdev_core_ops saa7706h_core_ops = {
  349 + .g_chip_ident = saa7706h_g_chip_ident,
  350 + .queryctrl = saa7706h_queryctrl,
  351 + .g_ctrl = saa7706h_g_ctrl,
  352 + .s_ctrl = saa7706h_s_ctrl,
  353 +};
  354 +
  355 +static const struct v4l2_subdev_ops saa7706h_ops = {
  356 + .core = &saa7706h_core_ops,
  357 +};
  358 +
  359 +/*
  360 + * Generic i2c probe
  361 + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  362 + */
  363 +
  364 +static int __devinit saa7706h_probe(struct i2c_client *client,
  365 + const struct i2c_device_id *id)
  366 +{
  367 + struct saa7706h_state *state;
  368 + struct v4l2_subdev *sd;
  369 + int err;
  370 +
  371 + /* Check if the adapter supports the needed features */
  372 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
  373 + return -EIO;
  374 +
  375 + v4l_info(client, "chip found @ 0x%02x (%s)\n",
  376 + client->addr << 1, client->adapter->name);
  377 +
  378 + state = kmalloc(sizeof(struct saa7706h_state), GFP_KERNEL);
  379 + if (state == NULL)
  380 + return -ENOMEM;
  381 + sd = &state->sd;
  382 + v4l2_i2c_subdev_init(sd, client, &saa7706h_ops);
  383 +
  384 + /* check the rom versions */
  385 + err = saa7706h_get_reg16(sd, SAA7706H_DSP1_ROM_VER);
  386 + if (err < 0)
  387 + goto err;
  388 + if (err != SUPPORTED_DSP1_ROM_VER)
  389 + v4l2_warn(sd, "Unknown DSP1 ROM code version: 0x%x\n", err);
  390 +
  391 + state->muted = 1;
  392 +
  393 + /* startup in a muted state */
  394 + err = saa7706h_mute(sd);
  395 + if (err)
  396 + goto err;
  397 +
  398 + return 0;
  399 +
  400 +err:
  401 + v4l2_device_unregister_subdev(sd);
  402 + kfree(to_state(sd));
  403 +
  404 + printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", err);
  405 +
  406 + return err;
  407 +}
  408 +
  409 +static int __devexit saa7706h_remove(struct i2c_client *client)
  410 +{
  411 + struct v4l2_subdev *sd = i2c_get_clientdata(client);
  412 +
  413 + saa7706h_mute(sd);
  414 + v4l2_device_unregister_subdev(sd);
  415 + kfree(to_state(sd));
  416 + return 0;
  417 +}
  418 +
  419 +static const struct i2c_device_id saa7706h_id[] = {
  420 + {DRIVER_NAME, 0},
  421 + {},
  422 +};
  423 +
  424 +MODULE_DEVICE_TABLE(i2c, saa7706h_id);
  425 +
  426 +static struct i2c_driver saa7706h_driver = {
  427 + .driver = {
  428 + .owner = THIS_MODULE,
  429 + .name = DRIVER_NAME,
  430 + },
  431 + .probe = saa7706h_probe,
  432 + .remove = saa7706h_remove,
  433 + .id_table = saa7706h_id,
  434 +};
  435 +
  436 +static __init int saa7706h_init(void)
  437 +{
  438 + return i2c_add_driver(&saa7706h_driver);
  439 +}
  440 +
  441 +static __exit void saa7706h_exit(void)
  442 +{
  443 + i2c_del_driver(&saa7706h_driver);
  444 +}
  445 +
  446 +module_init(saa7706h_init);
  447 +module_exit(saa7706h_exit);
  448 +
  449 +MODULE_DESCRIPTION("SAA7706H Car Radio DSP driver");
  450 +MODULE_AUTHOR("Mocean Laboratories");
  451 +MODULE_LICENSE("GPL v2");
include/media/v4l2-chip-ident.h
... ... @@ -155,6 +155,9 @@
155 155 /* module adv7343: just ident 7343 */
156 156 V4L2_IDENT_ADV7343 = 7343,
157 157  
  158 + /* module saa7706h: just ident 7706 */
  159 + V4L2_IDENT_SAA7706H = 7706,
  160 +
158 161 /* module wm8739: just ident 8739 */
159 162 V4L2_IDENT_WM8739 = 8739,
160 163