V4L/DVB (10759): cx18: Convert GPIO connected functions to act as v4l2_subdevices

Convert GPIO line functions, such a audio routing and device resets, to
v4l2_subdevices.  This essentially completes the conversion of cx18 to the
v4l2_device/v4l2_subdevice framework.  No regression testing has taken place as
of yet.  Also an ivtv legacy bug with GPIO mux routing and going to/from radio
mode was commented, but not fixed.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Andy Walls 2009-02-21 18:42:49 -03:00 committed by Mauro Carvalho Chehab
parent ff2a200180
commit eefe1010a4
12 changed files with 285 additions and 130 deletions

View file

@ -56,7 +56,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_CS5345,
.hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
CX18_HW_CS5345 | CX18_HW_DVB,
CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@ -102,7 +102,7 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_CS5345,
.hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
CX18_HW_CS5345 | CX18_HW_DVB,
CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@ -155,7 +155,7 @@ static const struct cx18_card cx18_card_h900 = {
.comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@ -202,7 +202,7 @@ static const struct cx18_card cx18_card_mpc718 = {
.comment = "Analog video capture works; some audio line in may not.\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@ -252,8 +252,8 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = {
.comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_GPIO_AUDIO_MUX,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_AUDIO_MUX,
.hw_muxer = CX18_HW_GPIO_MUX,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@ -307,7 +307,7 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@ -351,8 +351,9 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_GPIO_AUDIO_MUX,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_AUDIO_MUX,
.hw_muxer = CX18_HW_GPIO_MUX,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,

View file

@ -27,7 +27,8 @@
#define CX18_HW_CS5345 (1 << 2)
#define CX18_HW_DVB (1 << 3)
#define CX18_HW_418_AV (1 << 4)
#define CX18_HW_GPIO_AUDIO_MUX (1 << 5)
#define CX18_HW_GPIO_MUX (1 << 5)
#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
/* video inputs */
#define CX18_CARD_INPUT_VID_TUNER 1

View file

@ -22,11 +22,9 @@
*/
#include "cx18-driver.h"
#include "cx18-av-core.h"
#include "cx18-cards.h"
#include "cx18-ioctl.h"
#include "cx18-audio.h"
#include "cx18-i2c.h"
#include "cx18-mailbox.h"
#include "cx18-controls.h"

View file

@ -684,7 +684,6 @@ static void cx18_init_subdevs(struct cx18 *cx)
continue;
switch (device) {
case CX18_HW_GPIO_AUDIO_MUX:
case CX18_HW_DVB:
case CX18_HW_TVEEPROM:
/* These subordinate devices do not use probing */
@ -695,6 +694,16 @@ static void cx18_init_subdevs(struct cx18 *cx)
/* Just note that the card uses it (i.e. has analog) */
cx->hw_flags |= device;
break;
case CX18_HW_GPIO_RESET_CTRL:
/*
* The Reset Controller gets probed and added to
* hw_flags earlier for i2c adapter/bus initialization
*/
break;
case CX18_HW_GPIO_MUX:
if (cx18_gpio_register(cx, device) == 0)
cx->hw_flags |= device;
break;
default:
if (cx18_i2c_register(cx, i) == 0)
cx->hw_flags |= device;
@ -793,7 +802,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET);
cx18_init_scb(cx);
/* Initialize GPIO early so I2C device resets can be performed */
cx18_gpio_init(cx);
/* Initialize integrated A/V decoder early to set PLLs, just in case */
@ -802,9 +810,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
CX18_ERR("Could not register A/V decoder subdevice\n");
goto free_map;
}
/* Initialize the A/V decoder PLLs to sane defaults */
cx18_call_hw(cx, CX18_HW_418_AV, core, init, (u32) CX18_AV_INIT_PLLS);
/* Initialize GPIO Reset Controller to do chip resets during i2c init */
if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0)
CX18_WARN("Could not register GPIO reset controller"
"subdevice; proceeding anyway.\n");
else
cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL;
}
/* active i2c */
CX18_DEBUG_INFO("activating i2c...\n");
retval = init_cx18_i2c(cx);

View file

@ -449,7 +449,7 @@ struct cx18 {
struct pci_dev *pci_dev;
struct v4l2_device v4l2_dev;
struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */
struct v4l2_subdev *sd_extmux; /* External audio multiplexer sub-dev */
struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
const struct cx18_card *card; /* card information */
const char *card_name; /* full name of the card */
@ -534,6 +534,8 @@ struct cx18 {
u32 gpio_dir;
u32 gpio_val;
struct mutex gpio_lock;
struct v4l2_subdev sd_gpiomux;
struct v4l2_subdev sd_resetctrl;
/* v4l2 and User settings */

View file

@ -46,6 +46,9 @@
* gpio13: cs5345 reset pin
*/
/*
* File scope utility functions
*/
static void gpio_write(struct cx18 *cx)
{
u32 dir_lo = cx->gpio_dir & 0xffff;
@ -63,73 +66,201 @@ static void gpio_write(struct cx18 *cx)
CX18_REG_GPIO_OUT2, val_hi, dir_hi);
}
void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
{
const struct cx18_gpio_i2c_slave_reset *p;
p = &cx->card->gpio_i2c_slave_reset;
if ((p->active_lo_mask | p->active_hi_mask) == 0)
if (mask == 0)
return;
/* Assuming that the masks are a subset of the bits in gpio_dir */
mutex_lock(&cx->gpio_lock);
cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
}
static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
unsigned int assert_msecs,
unsigned int recovery_msecs)
{
u32 mask;
mask = active_lo | active_hi;
if (mask == 0)
return;
/*
* Assuming that active_hi and active_lo are a subsets of the bits in
* gpio_dir. Also assumes that active_lo and active_hi don't overlap
* in any bit position
*/
/* Assert */
mutex_lock(&cx->gpio_lock);
cx->gpio_val =
(cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
gpio_write(cx);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
gpio_update(cx, mask, ~active_lo);
schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
/* Deassert */
cx->gpio_val =
(cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
gpio_write(cx);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
mutex_unlock(&cx->gpio_lock);
gpio_update(cx, mask, ~active_hi);
schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
}
void cx18_reset_ir_gpio(void *data)
/*
* GPIO Multiplexer - logical device
*/
static int gpiomux_log_status(struct v4l2_subdev *sd)
{
struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
struct cx18 *cx = v4l2_get_subdevdata(sd);
mutex_lock(&cx->gpio_lock);
CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
cx->gpio_dir, cx->gpio_val);
mutex_unlock(&cx->gpio_lock);
return 0;
}
static int gpiomux_s_radio(struct v4l2_subdev *sd)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
/*
* FIXME - work out the cx->active/audio_input mess - this is
* intended to handle the switch to radio mode and set the
* audio routing, but we need to update the state in cx
*/
gpio_update(cx, cx->card->gpio_audio_input.mask,
cx->card->gpio_audio_input.radio);
return 0;
}
static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
u32 data;
switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
case 1:
data = cx->card->gpio_audio_input.linein;
break;
case 0:
data = cx->card->gpio_audio_input.tuner;
break;
default:
/*
* FIXME - work out the cx->active/audio_input mess - this is
* intended to handle the switch from radio mode and set the
* audio routing, but we need to update the state in cx
*/
data = cx->card->gpio_audio_input.tuner;
break;
}
gpio_update(cx, cx->card->gpio_audio_input.mask, data);
return 0;
}
static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
const struct v4l2_routing *route)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
u32 data;
switch (route->input) {
case 0:
data = cx->card->gpio_audio_input.tuner;
break;
case 1:
data = cx->card->gpio_audio_input.linein;
break;
case 2:
data = cx->card->gpio_audio_input.radio;
break;
default:
return -EINVAL;
}
gpio_update(cx, cx->card->gpio_audio_input.mask, data);
return 0;
}
static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
.log_status = gpiomux_log_status,
};
static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
.s_std = gpiomux_s_std,
.s_radio = gpiomux_s_radio,
};
static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
.s_routing = gpiomux_s_audio_routing,
};
static const struct v4l2_subdev_ops gpiomux_ops = {
.core = &gpiomux_core_ops,
.tuner = &gpiomux_tuner_ops,
.audio = &gpiomux_audio_ops,
};
/*
* GPIO Reset Controller - logical device
*/
static int resetctrl_log_status(struct v4l2_subdev *sd)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
mutex_lock(&cx->gpio_lock);
CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
cx->gpio_dir, cx->gpio_val);
mutex_unlock(&cx->gpio_lock);
return 0;
}
static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
const struct cx18_gpio_i2c_slave_reset *p;
p = &cx->card->gpio_i2c_slave_reset;
if (p->ir_reset_mask == 0)
return;
CX18_DEBUG_INFO("Resetting IR microcontroller\n");
/*
Assert timing for the Z8F0811 on HVR-1600 boards:
1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
(6,601,085 nanoseconds ~= 7 milliseconds)
3. DBG pin must be high before chip exits reset for normal operation.
DBG is open drain and hopefully pulled high since we don't
normally drive it (GPIO 1?) for the HVR-1600
4. Z8F0811 won't exit reset until RESET is deasserted
*/
mutex_lock(&cx->gpio_lock);
cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
/*
Zilog comes out of reset, loads reset vector address and executes
from there. Required recovery delay unknown.
*/
mutex_lock(&cx->gpio_lock);
cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
switch (val) {
case CX18_GPIO_RESET_I2C:
gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
p->msecs_asserted, p->msecs_recovery);
break;
case CX18_GPIO_RESET_Z8F0811:
/*
* Assert timing for the Z8F0811 on HVR-1600 boards:
* 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
* initiate
* 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
* cycles (6,601,085 nanoseconds ~= 7 milliseconds)
* 3. DBG pin must be high before chip exits reset for normal
* operation. DBG is open drain and hopefully pulled high
* since we don't normally drive it (GPIO 1?) for the
* HVR-1600
* 4. Z8F0811 won't exit reset until RESET is deasserted
* 5. Zilog comes out of reset, loads reset vector address and
* executes from there. Required recovery delay unknown.
*/
gpio_reset_seq(cx, p->ir_reset_mask, 0,
p->msecs_asserted, p->msecs_recovery);
break;
case CX18_GPIO_RESET_XC2028:
if (cx->card->tuners[0].tuner == TUNER_XC2028)
gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
1, 1);
break;
}
return 0;
}
EXPORT_SYMBOL(cx18_reset_ir_gpio);
/* This symbol is exported for use by an infrared module for the IR-blaster */
static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
.log_status = resetctrl_log_status,
.reset = resetctrl_reset,
};
static const struct v4l2_subdev_ops resetctrl_ops = {
.core = &resetctrl_core_ops,
};
/*
* External entry points
*/
void cx18_gpio_init(struct cx18 *cx)
{
mutex_lock(&cx->gpio_lock);
@ -156,6 +287,49 @@ void cx18_gpio_init(struct cx18 *cx)
mutex_unlock(&cx->gpio_lock);
}
int cx18_gpio_register(struct cx18 *cx, u32 hw)
{
struct v4l2_subdev *sd;
const struct v4l2_subdev_ops *ops;
char *str;
switch (hw) {
case CX18_HW_GPIO_MUX:
sd = &cx->sd_gpiomux;
ops = &gpiomux_ops;
str = "gpio mux";
break;
case CX18_HW_GPIO_RESET_CTRL:
sd = &cx->sd_resetctrl;
ops = &resetctrl_ops;
str = "gpio reset ctrl";
break;
default:
return -EINVAL;
}
v4l2_subdev_init(sd, ops);
v4l2_set_subdevdata(sd, cx);
snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
sd->grp_id = hw;
return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
}
void cx18_reset_ir_gpio(void *data)
{
struct cx18 *cx = to_cx18((struct v4l2_device *)data);
if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
return;
CX18_DEBUG_INFO("Resetting IR microcontroller\n");
v4l2_subdev_call(&cx->sd_resetctrl,
core, reset, CX18_GPIO_RESET_Z8F0811);
}
EXPORT_SYMBOL(cx18_reset_ir_gpio);
/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
/* Xceive tuner reset function */
int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
{
@ -163,56 +337,11 @@ int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
struct cx18_i2c_algo_callback_data *cb_data = algo->data;
struct cx18 *cx = cb_data->cx;
if (cmd != XC2028_TUNER_RESET)
if (cmd != XC2028_TUNER_RESET ||
cx->card->tuners[0].tuner != TUNER_XC2028)
return 0;
CX18_DEBUG_INFO("Resetting tuner\n");
mutex_lock(&cx->gpio_lock);
cx->gpio_val &= ~(1 << cx->card->xceive_pin);
gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
schedule_timeout_interruptible(msecs_to_jiffies(1));
mutex_lock(&cx->gpio_lock);
cx->gpio_val |= 1 << cx->card->xceive_pin;
gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
schedule_timeout_interruptible(msecs_to_jiffies(1));
return 0;
}
int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
{
struct v4l2_routing *route = arg;
u32 mask, data;
switch (command) {
case VIDIOC_INT_S_AUDIO_ROUTING:
if (route->input > 2)
return -EINVAL;
mask = cx->card->gpio_audio_input.mask;
switch (route->input) {
case 0:
data = cx->card->gpio_audio_input.tuner;
break;
case 1:
data = cx->card->gpio_audio_input.linein;
break;
case 2:
default:
data = cx->card->gpio_audio_input.radio;
break;
}
break;
default:
return -EINVAL;
}
if (mask) {
mutex_lock(&cx->gpio_lock);
cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
}
return 0;
CX18_DEBUG_INFO("Resetting XCeive tuner\n");
return v4l2_subdev_call(&cx->sd_resetctrl,
core, reset, CX18_GPIO_RESET_XC2028);
}

View file

@ -22,7 +22,13 @@
*/
void cx18_gpio_init(struct cx18 *cx);
void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
int cx18_gpio_register(struct cx18 *cx, u32 hw);
enum cx18_gpio_reset_type {
CX18_GPIO_RESET_I2C = 0,
CX18_GPIO_RESET_Z8F0811 = 1,
CX18_GPIO_RESET_XC2028 = 2,
};
void cx18_reset_ir_gpio(void *data);
int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value);
int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);

View file

@ -26,7 +26,6 @@
#include "cx18-io.h"
#include "cx18-cards.h"
#include "cx18-gpio.h"
#include "cx18-av-core.h"
#include "cx18-i2c.h"
#include "cx18-irq.h"
@ -49,7 +48,8 @@ static const u8 hw_addrs[] = {
CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */
0, /* CX18_HW_DVB */
0, /* CX18_HW_418_AV */
0, /* CX18_HW_GPIO_AUDIO_MUX */
0, /* CX18_HW_GPIO_MUX */
0, /* CX18_HW_GPIO_RESET_CTRL */
};
/* This array should match the CX18_HW_ defines */
@ -60,7 +60,8 @@ static const u8 hw_bus[] = {
0, /* CX18_HW_CS5345 */
0, /* CX18_HW_DVB */
0, /* CX18_HW_418_AV */
0, /* CX18_HW_GPIO_AUDIO_MUX */
0, /* CX18_HW_GPIO_MUX */
0, /* CX18_HW_GPIO_RESET_CTRL */
};
/* This array should match the CX18_HW_ defines */
@ -70,7 +71,8 @@ static const char * const hw_modules[] = {
"cs5345", /* CX18_HW_CS5345 */
NULL, /* CX18_HW_DVB */
NULL, /* CX18_HW_418_AV */
NULL, /* CX18_HW_GPIO_AUDIO_MUX */
NULL, /* CX18_HW_GPIO_MUX */
NULL, /* CX18_HW_GPIO_RESET_CTRL */
};
/* This array should match the CX18_HW_ defines */
@ -80,7 +82,8 @@ static const char * const hw_devicenames[] = {
"cs5345",
"cx23418_DTV",
"cx23418_AV",
"gpio_audio_mux",
"gpio_mux",
"gpio_reset_ctrl",
};
int cx18_i2c_register(struct cx18 *cx, unsigned idx)
@ -262,7 +265,8 @@ int init_cx18_i2c(struct cx18 *cx)
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
cx18_reset_i2c_slaves_gpio(cx);
cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
core, reset, (u32) CX18_GPIO_RESET_I2C);
return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
i2c_bit_add_bus(&cx->i2c_adap[1]);

View file

@ -940,7 +940,8 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
u32 val = *(u32 *)arg;
if ((val == 0) || (val & 0x01))
cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
(u32) CX18_GPIO_RESET_Z8F0811);
break;
}

View file

@ -32,7 +32,6 @@
#include "cx18-streams.h"
#include "cx18-cards.h"
#include "cx18-scb.h"
#include "cx18-av-core.h"
#include "cx18-dvb.h"
#define CX18_DSP0_INTERRUPT_MASK 0xd0004C

View file

@ -25,7 +25,6 @@
#include "cx18-vbi.h"
#include "cx18-ioctl.h"
#include "cx18-queue.h"
#include "cx18-av-core.h"
/*
* Raster Reference/Protection (RP) bytes, used in Start/End Active

View file

@ -21,7 +21,6 @@
#include "cx18-driver.h"
#include "cx18-video.h"
#include "cx18-av-core.h"
#include "cx18-cards.h"
void cx18_video_set_io(struct cx18 *cx)