},
        .gpio_init.initial_value = 0x3001,
        .gpio_init.direction = 0x3001,
+       .gpio_i2c_slave_reset = {
+               .active_lo_mask = 0x3001,
+               .msecs_asserted = 10,
+               .msecs_recovery = 40,
+       },
        .i2c = &cx18_i2c_std,
 };
 
        },
        .gpio_init.initial_value = 0x3001,
        .gpio_init.direction = 0x3001,
+       .gpio_i2c_slave_reset = {
+               .active_lo_mask = 0x3001,
+               .msecs_asserted = 10,
+               .msecs_recovery = 40,
+       },
        .i2c = &cx18_i2c_std,
 };
 
 
        u32 initial_value;
 };
 
+struct cx18_gpio_i2c_slave_reset {
+       u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */
+       u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
+       int msecs_asserted; /* time period reset must remain asserted */
+       int msecs_recovery; /* time after deassert for chips to be ready */
+};
+
 struct cx18_card_tuner {
        v4l2_std_id std;        /* standard for which the tuner is suitable */
        int         tuner;      /* tuner ID (from tuner.h) */
 
        /* GPIO card-specific settings */
        u8 xceive_pin;          /* XCeive tuner GPIO reset pin */
-       struct cx18_gpio_init           gpio_init;
+       struct cx18_gpio_init            gpio_init;
+       struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
 
        struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
        struct cx18_card_tuner_i2c *i2c;
 
        write_reg(((dir & 0xffff) << 16) | (val & 0xffff),
                        CX18_REG_GPIO_OUT1);
        write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2);
-       write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
+       write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
                        CX18_REG_GPIO_OUT2);
 }
 
+void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
+{
+       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)
+               return;
+
+       /* Assuming that the masks are a subset of the bits in gpio_dir */
+
+       /* Assert */
+       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));
+
+       /* 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));
+}
+
 void cx18_gpio_init(struct cx18 *cx)
 {
        cx->gpio_dir = cx->card->gpio_init.direction;
 
  */
 
 void cx18_gpio_init(struct cx18 *cx);
+void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
 int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
 
        cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
        cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
 
+       cx18_reset_i2c_slaves_gpio(cx);
+
        return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
                i2c_bit_add_bus(&cx->i2c_adap[1]);
 }