[media] cx23885: Enable audio line in support from the back panel
authorSteven Toth <stoth@kernellabs.com>
Mon, 10 Oct 2011 14:09:55 +0000 (11:09 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 14 Oct 2011 20:18:50 +0000 (17:18 -0300)
Add code to program the flatiron internal i2c ADC and pass the
appropriate audio mux enums to the cx25840 driver.

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cx23885/cx23885-cards.c
drivers/media/video/cx23885/cx23885-video.c

index 75d77c2db5c96beb499a22d24e84cd4c6c470307..969a9a336ac8e8efe160e7630e95c9bc211471a2 100644 (file)
@@ -106,12 +106,14 @@ struct cx23885_board cx23885_boards[] = {
                        .vmux   =       CX25840_VIN7_CH3 |
                                        CX25840_VIN5_CH2 |
                                        CX25840_VIN2_CH1,
+                       .amux   = CX25840_AUDIO8,
                        .gpio0  = 0,
                }, {
                        .type   = CX23885_VMUX_COMPOSITE1,
                        .vmux   =       CX25840_VIN7_CH3 |
                                        CX25840_VIN4_CH2 |
                                        CX25840_VIN6_CH1,
+                       .amux   = CX25840_AUDIO7,
                        .gpio0  = 0,
                }, {
                        .type   = CX23885_VMUX_SVIDEO,
@@ -119,6 +121,7 @@ struct cx23885_board cx23885_boards[] = {
                                        CX25840_VIN4_CH2 |
                                        CX25840_VIN8_CH1 |
                                        CX25840_SVIDEO_ON,
+                       .amux   = CX25840_AUDIO7,
                        .gpio0  = 0,
                } },
        },
index 44a63c4de1227fd828ec10f666ca0d499141f4c9..adc8f78d4c58bde9621d8dd9b90667d8afbb0dc7 100644 (file)
@@ -417,6 +417,71 @@ static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
        mutex_unlock(&dev->lock);
 }
 
+static int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data)
+{
+       /* 8 bit registers, 8 bit values */
+       u8 buf[] = { reg, data };
+
+       struct i2c_msg msg = { .addr = 0x98 >> 1,
+               .flags = 0, .buf = buf, .len = 2 };
+
+       return i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg, 1);
+}
+
+static u8 cx23885_flatiron_read(struct cx23885_dev *dev, u8 reg)
+{
+       /* 8 bit registers, 8 bit values */
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+
+       struct i2c_msg msg[] = {
+               { .addr = 0x98 >> 1, .flags = 0, .buf = b0, .len = 1 },
+               { .addr = 0x98 >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1 }
+       };
+
+       ret = i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg[0], 2);
+       if (ret != 2)
+               printk(KERN_ERR "%s() error\n", __func__);
+
+       return b1[0];
+}
+
+static void cx23885_flatiron_dump(struct cx23885_dev *dev)
+{
+       int i;
+       dprintk(1, "Flatiron dump\n");
+       for (i = 0; i < 0x24; i++) {
+               dprintk(1, "FI[%02x] = %02x\n", i,
+                       cx23885_flatiron_read(dev, i));
+       }
+}
+
+static int cx23885_flatiron_mux(struct cx23885_dev *dev, int input)
+{
+       u8 val;
+       dprintk(1, "%s(input = %d)\n", __func__, input);
+
+       if (input == 1)
+               val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) & ~FLD_CH_SEL;
+       else if (input == 2)
+               val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) | FLD_CH_SEL;
+       else
+               return -EINVAL;
+
+       val |= 0x20; /* Enable clock to delta-sigma and dec filter */
+
+       cx23885_flatiron_write(dev, CH_PWR_CTRL1, val);
+
+       /* Wake up */
+       cx23885_flatiron_write(dev, CH_PWR_CTRL2, 0);
+
+       if (video_debug)
+               cx23885_flatiron_dump(dev);
+
+       return 0;
+}
+
 static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
 {
        dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
@@ -437,6 +502,17 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
        v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
                        INPUT(input)->vmux, 0, 0);
 
+       if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) {
+               /* Configure audio routing */
+               v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
+                       INPUT(input)->amux, 0, 0);
+
+               if (INPUT(input)->amux == CX25840_AUDIO7)
+                       cx23885_flatiron_mux(dev, 1);
+               else if (INPUT(input)->amux == CX25840_AUDIO6)
+                       cx23885_flatiron_mux(dev, 2);
+       }
+
        return 0;
 }