0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/delay.h>
0013
0014 #include "ccs.h"
0015 #include "ccs-limits.h"
0016
0017 static int ccs_write_addr_8s(struct ccs_sensor *sensor,
0018 const struct ccs_reg_8 *regs, int len)
0019 {
0020 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
0021 int rval;
0022
0023 for (; len > 0; len--, regs++) {
0024 rval = ccs_write_addr(sensor, regs->reg, regs->val);
0025 if (rval < 0) {
0026 dev_err(&client->dev,
0027 "error %d writing reg 0x%4.4x, val 0x%2.2x",
0028 rval, regs->reg, regs->val);
0029 return rval;
0030 }
0031 }
0032
0033 return 0;
0034 }
0035
0036 static int jt8ew9_limits(struct ccs_sensor *sensor)
0037 {
0038 if (sensor->minfo.revision_number < 0x0300)
0039 sensor->frame_skip = 1;
0040
0041
0042
0043 ccs_replace_limit(sensor, CCS_L_ANALOG_GAIN_CODE_MIN, 0, 59);
0044 ccs_replace_limit(sensor, CCS_L_ANALOG_GAIN_CODE_MAX, 0, 6000);
0045
0046 return 0;
0047 }
0048
0049 static int jt8ew9_post_poweron(struct ccs_sensor *sensor)
0050 {
0051 static const struct ccs_reg_8 regs[] = {
0052 { 0x30a3, 0xd8 },
0053 { 0x30ae, 0x00 },
0054 { 0x30af, 0xd0 },
0055 { 0x322d, 0x04 },
0056 { 0x3255, 0x0f },
0057 { 0x3256, 0x15 },
0058 { 0x3258, 0x70 },
0059 { 0x3259, 0x70 },
0060 { 0x325f, 0x7c },
0061 { 0x3302, 0x06 },
0062 { 0x3304, 0x00 },
0063 { 0x3307, 0x22 },
0064 { 0x3308, 0x8d },
0065 { 0x331e, 0x0f },
0066 { 0x3320, 0x30 },
0067 { 0x3321, 0x11 },
0068 { 0x3322, 0x98 },
0069 { 0x3323, 0x64 },
0070 { 0x3325, 0x83 },
0071 { 0x3330, 0x18 },
0072 { 0x333c, 0x01 },
0073 { 0x3345, 0x2f },
0074 { 0x33de, 0x38 },
0075
0076 { 0x32e0, 0x05 },
0077 { 0x32e1, 0x05 },
0078 { 0x32e2, 0x04 },
0079 { 0x32e5, 0x04 },
0080 { 0x32e6, 0x04 },
0081
0082 };
0083
0084 return ccs_write_addr_8s(sensor, regs, ARRAY_SIZE(regs));
0085 }
0086
0087 const struct ccs_quirk smiapp_jt8ew9_quirk = {
0088 .limits = jt8ew9_limits,
0089 .post_poweron = jt8ew9_post_poweron,
0090 };
0091
0092 static int imx125es_post_poweron(struct ccs_sensor *sensor)
0093 {
0094
0095 static const struct ccs_reg_8 regs[] = {
0096
0097
0098
0099
0100 { 0x3302, 0x01 },
0101 { 0x302d, 0x00 },
0102 { 0x3b08, 0x8c },
0103 };
0104
0105 return ccs_write_addr_8s(sensor, regs, ARRAY_SIZE(regs));
0106 }
0107
0108 const struct ccs_quirk smiapp_imx125es_quirk = {
0109 .post_poweron = imx125es_post_poweron,
0110 };
0111
0112 static int jt8ev1_limits(struct ccs_sensor *sensor)
0113 {
0114 ccs_replace_limit(sensor, CCS_L_X_ADDR_MAX, 0, 4271);
0115 ccs_replace_limit(sensor, CCS_L_MIN_LINE_BLANKING_PCK_BIN, 0, 184);
0116
0117 return 0;
0118 }
0119
0120 static int jt8ev1_post_poweron(struct ccs_sensor *sensor)
0121 {
0122 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
0123 int rval;
0124 static const struct ccs_reg_8 regs[] = {
0125 { 0x3031, 0xcd },
0126 { 0x30a3, 0xd0 },
0127 { 0x3237, 0x00 },
0128 { 0x3238, 0x43 },
0129 { 0x3301, 0x06 },
0130 { 0x3302, 0x06 },
0131 { 0x3304, 0x00 },
0132 { 0x3305, 0x88 },
0133 { 0x332a, 0x14 },
0134 { 0x332c, 0x6b },
0135 { 0x3336, 0x01 },
0136 { 0x333f, 0x1f },
0137 { 0x3355, 0x00 },
0138 { 0x3356, 0x20 },
0139 { 0x33bf, 0x20 },
0140 { 0x33c9, 0x20 },
0141 { 0x33ce, 0x30 },
0142 { 0x33cf, 0xec },
0143 { 0x3328, 0x80 },
0144 };
0145 static const struct ccs_reg_8 regs_96[] = {
0146 { 0x30ae, 0x00 },
0147 { 0x30af, 0xd0 },
0148 { 0x30b0, 0x01 },
0149 };
0150
0151 rval = ccs_write_addr_8s(sensor, regs, ARRAY_SIZE(regs));
0152 if (rval < 0)
0153 return rval;
0154
0155 switch (sensor->hwcfg.ext_clk) {
0156 case 9600000:
0157 return ccs_write_addr_8s(sensor, regs_96,
0158 ARRAY_SIZE(regs_96));
0159 default:
0160 dev_warn(&client->dev, "no MSRs for %d Hz ext_clk\n",
0161 sensor->hwcfg.ext_clk);
0162 return 0;
0163 }
0164 }
0165
0166 static int jt8ev1_pre_streamon(struct ccs_sensor *sensor)
0167 {
0168 return ccs_write_addr(sensor, 0x3328, 0x00);
0169 }
0170
0171 static int jt8ev1_post_streamoff(struct ccs_sensor *sensor)
0172 {
0173 int rval;
0174
0175
0176 rval = ccs_write_addr(sensor, 0x3205, 0x04);
0177 if (rval < 0)
0178 return rval;
0179
0180
0181 usleep_range(2000, 2050);
0182
0183
0184 rval = ccs_write_addr(sensor, 0x3205, 0x00);
0185 if (rval < 0)
0186 return rval;
0187
0188 return ccs_write_addr(sensor, 0x3328, 0x80);
0189 }
0190
0191 static int jt8ev1_init(struct ccs_sensor *sensor)
0192 {
0193 sensor->pll.flags |= CCS_PLL_FLAG_LANE_SPEED_MODEL |
0194 CCS_PLL_FLAG_LINK_DECOUPLED;
0195 sensor->pll.vt_lanes = 1;
0196 sensor->pll.op_lanes = sensor->pll.csi2.lanes;
0197
0198 return 0;
0199 }
0200
0201 const struct ccs_quirk smiapp_jt8ev1_quirk = {
0202 .limits = jt8ev1_limits,
0203 .post_poweron = jt8ev1_post_poweron,
0204 .pre_streamon = jt8ev1_pre_streamon,
0205 .post_streamoff = jt8ev1_post_streamoff,
0206 .init = jt8ev1_init,
0207 };
0208
0209 static int tcm8500md_limits(struct ccs_sensor *sensor)
0210 {
0211 ccs_replace_limit(sensor, CCS_L_MIN_PLL_IP_CLK_FREQ_MHZ, 0, 2700000);
0212
0213 return 0;
0214 }
0215
0216 const struct ccs_quirk smiapp_tcm8500md_quirk = {
0217 .limits = tcm8500md_limits,
0218 };