Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] saa7115: Implement i2c_board_info.platform_data

This patch implements i2c_board_info.platform_data, and some options to
override the default initialization table for the GM7113C and SAA7113
chips.

Signed-off-by: Jon Arne Jørgensen <jonarne@jonarne.no>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

Jon Arne Jørgensen and committed by
Mauro Carvalho Chehab
2ccf12af b9798bc1

+198 -9
+119 -9
drivers/media/i2c/saa7115.c
··· 225 225 0x00, 0x00 226 226 }; 227 227 228 - /* SAA7113/GM7113C init codes 229 - * It's important that R_14... R_17 == 0x00 230 - * for the gm7113c chip to deliver stable video 231 - */ 228 + /* This table has one illegal value, and some values that are not 229 + correct according to the datasheet initialization table. 230 + 231 + If you need a table with legal/default values tell the driver in 232 + i2c_board_info.platform_data, and you will get the gm7113c_init 233 + table instead. */ 234 + 235 + /* SAA7113 Init codes */ 232 236 static const unsigned char saa7113_init[] = { 233 237 R_01_INC_DELAY, 0x08, 234 238 R_02_INPUT_CNTL_1, 0xc2, 235 239 R_03_INPUT_CNTL_2, 0x30, 236 240 R_04_INPUT_CNTL_3, 0x00, 237 241 R_05_INPUT_CNTL_4, 0x00, 238 - R_06_H_SYNC_START, 0x89, 242 + R_06_H_SYNC_START, 0x89, /* Illegal value -119, 243 + * min. value = -108 (0x94) */ 239 244 R_07_H_SYNC_STOP, 0x0d, 240 - R_08_SYNC_CNTL, 0x88, 245 + R_08_SYNC_CNTL, 0x88, /* Not datasheet default. 246 + * HTC = VTR mode, should be 0x98 */ 241 247 R_09_LUMA_CNTL, 0x01, 242 248 R_0A_LUMA_BRIGHT_CNTL, 0x80, 243 249 R_0B_LUMA_CONTRAST_CNTL, 0x47, ··· 251 245 R_0D_CHROMA_HUE_CNTL, 0x00, 252 246 R_0E_CHROMA_CNTL_1, 0x01, 253 247 R_0F_CHROMA_GAIN_CNTL, 0x2a, 254 - R_10_CHROMA_CNTL_2, 0x08, 248 + R_10_CHROMA_CNTL_2, 0x08, /* Not datsheet default. 249 + * VRLN enabled, should be 0x00 */ 255 250 R_11_MODE_DELAY_CNTL, 0x0c, 256 - R_12_RT_SIGNAL_CNTL, 0x07, 251 + R_12_RT_SIGNAL_CNTL, 0x07, /* Not datasheet default, 252 + * should be 0x01 */ 253 + R_13_RT_X_PORT_OUT_CNTL, 0x00, 254 + R_14_ANAL_ADC_COMPAT_CNTL, 0x00, 255 + R_15_VGATE_START_FID_CHG, 0x00, 256 + R_16_VGATE_STOP, 0x00, 257 + R_17_MISC_VGATE_CONF_AND_MSB, 0x00, 258 + 259 + 0x00, 0x00 260 + }; 261 + 262 + /* GM7113C is a clone of the SAA7113 chip 263 + This init table is copied out of the saa7113 datasheet. 264 + In R_08 we enable "Automatic Field Detection" [AUFD], 265 + this is disabled when saa711x_set_v4lstd is called. */ 266 + static const unsigned char gm7113c_init[] = { 267 + R_01_INC_DELAY, 0x08, 268 + R_02_INPUT_CNTL_1, 0xc0, 269 + R_03_INPUT_CNTL_2, 0x33, 270 + R_04_INPUT_CNTL_3, 0x00, 271 + R_05_INPUT_CNTL_4, 0x00, 272 + R_06_H_SYNC_START, 0xe9, 273 + R_07_H_SYNC_STOP, 0x0d, 274 + R_08_SYNC_CNTL, 0x98, 275 + R_09_LUMA_CNTL, 0x01, 276 + R_0A_LUMA_BRIGHT_CNTL, 0x80, 277 + R_0B_LUMA_CONTRAST_CNTL, 0x47, 278 + R_0C_CHROMA_SAT_CNTL, 0x40, 279 + R_0D_CHROMA_HUE_CNTL, 0x00, 280 + R_0E_CHROMA_CNTL_1, 0x01, 281 + R_0F_CHROMA_GAIN_CNTL, 0x2a, 282 + R_10_CHROMA_CNTL_2, 0x00, 283 + R_11_MODE_DELAY_CNTL, 0x0c, 284 + R_12_RT_SIGNAL_CNTL, 0x01, 257 285 R_13_RT_X_PORT_OUT_CNTL, 0x00, 258 286 R_14_ANAL_ADC_COMPAT_CNTL, 0x00, 259 287 R_15_VGATE_START_FID_CHG, 0x00, ··· 1625 1585 1626 1586 /* ----------------------------------------------------------------------- */ 1627 1587 1588 + static void saa711x_write_platform_data(struct saa711x_state *state, 1589 + struct saa7115_platform_data *data) 1590 + { 1591 + struct v4l2_subdev *sd = &state->sd; 1592 + u8 work; 1593 + 1594 + if (state->ident != GM7113C && 1595 + state->ident != SAA7113) 1596 + return; 1597 + 1598 + if (data->saa7113_r08_htc) { 1599 + work = saa711x_read(sd, R_08_SYNC_CNTL); 1600 + work &= ~SAA7113_R_08_HTC_MASK; 1601 + work |= ((*data->saa7113_r08_htc) << SAA7113_R_08_HTC_OFFSET); 1602 + saa711x_write(sd, R_08_SYNC_CNTL, work); 1603 + } 1604 + 1605 + if (data->saa7113_r10_vrln) { 1606 + work = saa711x_read(sd, R_10_CHROMA_CNTL_2); 1607 + work &= ~SAA7113_R_10_VRLN_MASK; 1608 + if (*data->saa7113_r10_vrln) 1609 + work |= (1 << SAA7113_R_10_VRLN_OFFSET); 1610 + saa711x_write(sd, R_10_CHROMA_CNTL_2, work); 1611 + } 1612 + 1613 + if (data->saa7113_r10_ofts) { 1614 + work = saa711x_read(sd, R_10_CHROMA_CNTL_2); 1615 + work &= ~SAA7113_R_10_OFTS_MASK; 1616 + work |= (*data->saa7113_r10_ofts << SAA7113_R_10_OFTS_OFFSET); 1617 + saa711x_write(sd, R_10_CHROMA_CNTL_2, work); 1618 + } 1619 + 1620 + if (data->saa7113_r12_rts0) { 1621 + work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL); 1622 + work &= ~SAA7113_R_12_RTS0_MASK; 1623 + work |= (*data->saa7113_r12_rts0 << SAA7113_R_12_RTS0_OFFSET); 1624 + 1625 + /* According to the datasheet, 1626 + * SAA7113_RTS_DOT_IN should only be used on RTS1 */ 1627 + WARN_ON(*data->saa7113_r12_rts0 == SAA7113_RTS_DOT_IN); 1628 + saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work); 1629 + } 1630 + 1631 + if (data->saa7113_r12_rts1) { 1632 + work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL); 1633 + work &= ~SAA7113_R_12_RTS1_MASK; 1634 + work |= (*data->saa7113_r12_rts1 << SAA7113_R_12_RTS1_OFFSET); 1635 + saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work); 1636 + } 1637 + 1638 + if (data->saa7113_r13_adlsb) { 1639 + work = saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL); 1640 + work &= ~SAA7113_R_13_ADLSB_MASK; 1641 + if (*data->saa7113_r13_adlsb) 1642 + work |= (1 << SAA7113_R_13_ADLSB_OFFSET); 1643 + saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL, work); 1644 + } 1645 + } 1646 + 1628 1647 /** 1629 1648 * saa711x_detect_chip - Detects the saa711x (or clone) variant 1630 1649 * @client: I2C client structure. ··· 1792 1693 struct saa711x_state *state; 1793 1694 struct v4l2_subdev *sd; 1794 1695 struct v4l2_ctrl_handler *hdl; 1696 + struct saa7115_platform_data *pdata; 1795 1697 int ident; 1796 1698 char name[CHIP_VER_SIZE + 1]; 1797 1699 ··· 1856 1756 1857 1757 /* init to 60hz/48khz */ 1858 1758 state->crystal_freq = SAA7115_FREQ_24_576_MHZ; 1759 + pdata = client->dev.platform_data; 1859 1760 switch (state->ident) { 1860 1761 case SAA7111: 1861 1762 case SAA7111A: 1862 1763 saa711x_writeregs(sd, saa7111_init); 1863 1764 break; 1864 1765 case GM7113C: 1766 + saa711x_writeregs(sd, gm7113c_init); 1767 + break; 1865 1768 case SAA7113: 1866 - saa711x_writeregs(sd, saa7113_init); 1769 + if (pdata && pdata->saa7113_force_gm7113c_init) 1770 + saa711x_writeregs(sd, gm7113c_init); 1771 + else 1772 + saa711x_writeregs(sd, saa7113_init); 1867 1773 break; 1868 1774 default: 1869 1775 state->crystal_freq = SAA7115_FREQ_32_11_MHZ; ··· 1877 1771 } 1878 1772 if (state->ident > SAA7111A && state->ident != GM7113C) 1879 1773 saa711x_writeregs(sd, saa7115_init_misc); 1774 + 1775 + if (pdata) 1776 + saa711x_write_platform_data(state, pdata); 1777 + 1880 1778 saa711x_set_v4lstd(sd, V4L2_STD_NTSC); 1881 1779 v4l2_ctrl_handler_setup(hdl); 1882 1780
+15
drivers/media/i2c/saa711x_regs.h
··· 202 202 #define R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES 0xff 203 203 204 204 /* SAA7113 bit-masks */ 205 + #define SAA7113_R_08_HTC_OFFSET 3 206 + #define SAA7113_R_08_HTC_MASK (0x3 << SAA7113_R_08_HTC_OFFSET) 205 207 #define SAA7113_R_08_FSEL 0x40 206 208 #define SAA7113_R_08_AUFD 0x80 209 + 210 + #define SAA7113_R_10_VRLN_OFFSET 3 211 + #define SAA7113_R_10_VRLN_MASK (0x1 << SAA7113_R_10_VRLN_OFFSET) 212 + #define SAA7113_R_10_OFTS_OFFSET 6 213 + #define SAA7113_R_10_OFTS_MASK (0x3 << SAA7113_R_10_OFTS_OFFSET) 214 + 215 + #define SAA7113_R_12_RTS0_OFFSET 0 216 + #define SAA7113_R_12_RTS0_MASK (0xf << SAA7113_R_12_RTS0_OFFSET) 217 + #define SAA7113_R_12_RTS1_OFFSET 4 218 + #define SAA7113_R_12_RTS1_MASK (0xf << SAA7113_R_12_RTS1_OFFSET) 219 + 220 + #define SAA7113_R_13_ADLSB_OFFSET 7 221 + #define SAA7113_R_13_ADLSB_MASK (0x1 << SAA7113_R_13_ADLSB_OFFSET) 207 222 208 223 #if 0 209 224 /* Those structs will be used in the future for debug purposes */
+64
include/media/saa7115.h
··· 64 64 #define SAA7115_FREQ_FL_APLL (1 << 2) /* SA 3A[3], APLL, SAA7114/5 only */ 65 65 #define SAA7115_FREQ_FL_DOUBLE_ASCLK (1 << 3) /* SA 39, LRDIV, SAA7114/5 only */ 66 66 67 + /* ===== SAA7113 Config enums ===== */ 68 + 69 + /* Register 0x08 "Horizontal time constant" [Bit 3..4]: 70 + * Should be set to "Fast Locking Mode" according to the datasheet, 71 + * and that is the default setting in the gm7113c_init table. 72 + * saa7113_init sets this value to "VTR Mode". */ 73 + enum saa7113_r08_htc { 74 + SAA7113_HTC_TV_MODE = 0x00, 75 + SAA7113_HTC_VTR_MODE, /* Default for saa7113_init */ 76 + SAA7113_HTC_FAST_LOCKING_MODE = 0x03 /* Default for gm7113c_init */ 77 + }; 78 + 79 + /* Register 0x10 "Output format selection" [Bit 6..7]: 80 + * Defaults to ITU_656 as specified in datasheet. */ 81 + enum saa7113_r10_ofts { 82 + SAA7113_OFTS_ITU_656 = 0x0, /* Default */ 83 + SAA7113_OFTS_VFLAG_BY_VREF, 84 + SAA7113_OFTS_VFLAG_BY_DATA_TYPE 85 + }; 86 + 87 + /* Register 0x12 "Output control" [Bit 0..3 Or Bit 4..7]: 88 + * This is used to select what data is output on the RTS0 and RTS1 pins. 89 + * RTS1 [Bit 4..7] Defaults to DOT_IN. (This value can not be set for RTS0) 90 + * RTS0 [Bit 0..3] Defaults to VIPB in gm7113c_init as specified 91 + * in the datasheet, but is set to HREF_HS in the saa7113_init table. */ 92 + enum saa7113_r12_rts { 93 + SAA7113_RTS_DOT_IN = 0, /* OBS: Only for RTS1 (Default RTS1) */ 94 + SAA7113_RTS_VIPB, /* Default RTS0 For gm7113c_init */ 95 + SAA7113_RTS_GPSW, 96 + SAA7115_RTS_HL, 97 + SAA7113_RTS_VL, 98 + SAA7113_RTS_DL, 99 + SAA7113_RTS_PLIN, 100 + SAA7113_RTS_HREF_HS, /* Default RTS0 For saa7113_init */ 101 + SAA7113_RTS_HS, 102 + SAA7113_RTS_HQ, 103 + SAA7113_RTS_ODD, 104 + SAA7113_RTS_VS, 105 + SAA7113_RTS_V123, 106 + SAA7113_RTS_VGATE, 107 + SAA7113_RTS_VREF, 108 + SAA7113_RTS_FID 109 + }; 110 + 111 + struct saa7115_platform_data { 112 + /* saa7113 only: Force the use of the gm7113c_init table, 113 + * instead of the old saa7113_init table. */ 114 + bool saa7113_force_gm7113c_init; 115 + 116 + /* SAA7113/GM7113C Specific configurations */ 117 + enum saa7113_r08_htc *saa7113_r08_htc; /* [R_08 - Bit 3..4] */ 118 + 119 + bool *saa7113_r10_vrln; /* [R_10 - Bit 3] 120 + Disabled for gm7113c_init 121 + Enabled for saa7113c_init */ 122 + enum saa7113_r10_ofts *saa7113_r10_ofts; /* [R_10 - Bit 6..7] */ 123 + 124 + enum saa7113_r12_rts *saa7113_r12_rts0; /* [R_12 - Bit 0..3] */ 125 + enum saa7113_r12_rts *saa7113_r12_rts1; /* [R_12 - Bit 4..7] */ 126 + 127 + bool *saa7113_r13_adlsb; /* [R_13 - Bit 7] 128 + Default disabled */ 129 + }; 130 + 67 131 #endif 68 132