0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <linux/module.h>
0028
0029 #include <drm/drm_drv.h>
0030 #include <drm/drm_encoder_slave.h>
0031 #include <drm/drm_print.h>
0032 #include <drm/drm_probe_helper.h>
0033 #include <drm/i2c/sil164.h>
0034
0035 struct sil164_priv {
0036 struct sil164_encoder_params config;
0037 struct i2c_client *duallink_slave;
0038
0039 uint8_t saved_state[0x10];
0040 uint8_t saved_slave_state[0x10];
0041 };
0042
0043 #define to_sil164_priv(x) \
0044 ((struct sil164_priv *)to_encoder_slave(x)->slave_priv)
0045
0046 #define sil164_dbg(client, format, ...) do { \
0047 if (drm_debug_enabled(DRM_UT_KMS)) \
0048 dev_printk(KERN_DEBUG, &client->dev, \
0049 "%s: " format, __func__, ## __VA_ARGS__); \
0050 } while (0)
0051 #define sil164_info(client, format, ...) \
0052 dev_info(&client->dev, format, __VA_ARGS__)
0053 #define sil164_err(client, format, ...) \
0054 dev_err(&client->dev, format, __VA_ARGS__)
0055
0056 #define SIL164_I2C_ADDR_MASTER 0x38
0057 #define SIL164_I2C_ADDR_SLAVE 0x39
0058
0059
0060
0061 #define SIL164_VENDOR_LO 0x0
0062 #define SIL164_VENDOR_HI 0x1
0063 #define SIL164_DEVICE_LO 0x2
0064 #define SIL164_DEVICE_HI 0x3
0065 #define SIL164_REVISION 0x4
0066 #define SIL164_FREQ_MIN 0x6
0067 #define SIL164_FREQ_MAX 0x7
0068 #define SIL164_CONTROL0 0x8
0069 # define SIL164_CONTROL0_POWER_ON 0x01
0070 # define SIL164_CONTROL0_EDGE_RISING 0x02
0071 # define SIL164_CONTROL0_INPUT_24BIT 0x04
0072 # define SIL164_CONTROL0_DUAL_EDGE 0x08
0073 # define SIL164_CONTROL0_HSYNC_ON 0x10
0074 # define SIL164_CONTROL0_VSYNC_ON 0x20
0075 #define SIL164_DETECT 0x9
0076 # define SIL164_DETECT_INTR_STAT 0x01
0077 # define SIL164_DETECT_HOTPLUG_STAT 0x02
0078 # define SIL164_DETECT_RECEIVER_STAT 0x04
0079 # define SIL164_DETECT_INTR_MODE_RECEIVER 0x00
0080 # define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08
0081 # define SIL164_DETECT_OUT_MODE_HIGH 0x00
0082 # define SIL164_DETECT_OUT_MODE_INTR 0x10
0083 # define SIL164_DETECT_OUT_MODE_RECEIVER 0x20
0084 # define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30
0085 # define SIL164_DETECT_VSWING_STAT 0x80
0086 #define SIL164_CONTROL1 0xa
0087 # define SIL164_CONTROL1_DESKEW_ENABLE 0x10
0088 # define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5
0089 #define SIL164_GPIO 0xb
0090 #define SIL164_CONTROL2 0xc
0091 # define SIL164_CONTROL2_FILTER_ENABLE 0x01
0092 # define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1
0093 # define SIL164_CONTROL2_DUALLINK_MASTER 0x40
0094 # define SIL164_CONTROL2_SYNC_CONT 0x80
0095 #define SIL164_DUALLINK 0xd
0096 # define SIL164_DUALLINK_ENABLE 0x10
0097 # define SIL164_DUALLINK_SKEW_SHIFT 5
0098 #define SIL164_PLLZONE 0xe
0099 # define SIL164_PLLZONE_STAT 0x08
0100 # define SIL164_PLLZONE_FORCE_ON 0x10
0101 # define SIL164_PLLZONE_FORCE_HIGH 0x20
0102
0103
0104
0105 static void
0106 sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val)
0107 {
0108 uint8_t buf[] = {addr, val};
0109 int ret;
0110
0111 ret = i2c_master_send(client, buf, ARRAY_SIZE(buf));
0112 if (ret < 0)
0113 sil164_err(client, "Error %d writing to subaddress 0x%x\n",
0114 ret, addr);
0115 }
0116
0117 static uint8_t
0118 sil164_read(struct i2c_client *client, uint8_t addr)
0119 {
0120 uint8_t val;
0121 int ret;
0122
0123 ret = i2c_master_send(client, &addr, sizeof(addr));
0124 if (ret < 0)
0125 goto fail;
0126
0127 ret = i2c_master_recv(client, &val, sizeof(val));
0128 if (ret < 0)
0129 goto fail;
0130
0131 return val;
0132
0133 fail:
0134 sil164_err(client, "Error %d reading from subaddress 0x%x\n",
0135 ret, addr);
0136 return 0;
0137 }
0138
0139 static void
0140 sil164_save_state(struct i2c_client *client, uint8_t *state)
0141 {
0142 int i;
0143
0144 for (i = 0x8; i <= 0xe; i++)
0145 state[i] = sil164_read(client, i);
0146 }
0147
0148 static void
0149 sil164_restore_state(struct i2c_client *client, uint8_t *state)
0150 {
0151 int i;
0152
0153 for (i = 0x8; i <= 0xe; i++)
0154 sil164_write(client, i, state[i]);
0155 }
0156
0157 static void
0158 sil164_set_power_state(struct i2c_client *client, bool on)
0159 {
0160 uint8_t control0 = sil164_read(client, SIL164_CONTROL0);
0161
0162 if (on)
0163 control0 |= SIL164_CONTROL0_POWER_ON;
0164 else
0165 control0 &= ~SIL164_CONTROL0_POWER_ON;
0166
0167 sil164_write(client, SIL164_CONTROL0, control0);
0168 }
0169
0170 static void
0171 sil164_init_state(struct i2c_client *client,
0172 struct sil164_encoder_params *config,
0173 bool duallink)
0174 {
0175 sil164_write(client, SIL164_CONTROL0,
0176 SIL164_CONTROL0_HSYNC_ON |
0177 SIL164_CONTROL0_VSYNC_ON |
0178 (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) |
0179 (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) |
0180 (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0));
0181
0182 sil164_write(client, SIL164_DETECT,
0183 SIL164_DETECT_INTR_STAT |
0184 SIL164_DETECT_OUT_MODE_RECEIVER);
0185
0186 sil164_write(client, SIL164_CONTROL1,
0187 (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) |
0188 (((config->input_skew + 4) & 0x7)
0189 << SIL164_CONTROL1_DESKEW_INCR_SHIFT));
0190
0191 sil164_write(client, SIL164_CONTROL2,
0192 SIL164_CONTROL2_SYNC_CONT |
0193 (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) |
0194 (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT));
0195
0196 sil164_write(client, SIL164_PLLZONE, 0);
0197
0198 if (duallink)
0199 sil164_write(client, SIL164_DUALLINK,
0200 SIL164_DUALLINK_ENABLE |
0201 (((config->duallink_skew + 4) & 0x7)
0202 << SIL164_DUALLINK_SKEW_SHIFT));
0203 else
0204 sil164_write(client, SIL164_DUALLINK, 0);
0205 }
0206
0207
0208
0209 static void
0210 sil164_encoder_set_config(struct drm_encoder *encoder, void *params)
0211 {
0212 struct sil164_priv *priv = to_sil164_priv(encoder);
0213
0214 priv->config = *(struct sil164_encoder_params *)params;
0215 }
0216
0217 static void
0218 sil164_encoder_dpms(struct drm_encoder *encoder, int mode)
0219 {
0220 struct sil164_priv *priv = to_sil164_priv(encoder);
0221 bool on = (mode == DRM_MODE_DPMS_ON);
0222 bool duallink = (on && encoder->crtc->mode.clock > 165000);
0223
0224 sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on);
0225
0226 if (priv->duallink_slave)
0227 sil164_set_power_state(priv->duallink_slave, duallink);
0228 }
0229
0230 static void
0231 sil164_encoder_save(struct drm_encoder *encoder)
0232 {
0233 struct sil164_priv *priv = to_sil164_priv(encoder);
0234
0235 sil164_save_state(drm_i2c_encoder_get_client(encoder),
0236 priv->saved_state);
0237
0238 if (priv->duallink_slave)
0239 sil164_save_state(priv->duallink_slave,
0240 priv->saved_slave_state);
0241 }
0242
0243 static void
0244 sil164_encoder_restore(struct drm_encoder *encoder)
0245 {
0246 struct sil164_priv *priv = to_sil164_priv(encoder);
0247
0248 sil164_restore_state(drm_i2c_encoder_get_client(encoder),
0249 priv->saved_state);
0250
0251 if (priv->duallink_slave)
0252 sil164_restore_state(priv->duallink_slave,
0253 priv->saved_slave_state);
0254 }
0255
0256 static int
0257 sil164_encoder_mode_valid(struct drm_encoder *encoder,
0258 struct drm_display_mode *mode)
0259 {
0260 struct sil164_priv *priv = to_sil164_priv(encoder);
0261
0262 if (mode->clock < 32000)
0263 return MODE_CLOCK_LOW;
0264
0265 if (mode->clock > 330000 ||
0266 (mode->clock > 165000 && !priv->duallink_slave))
0267 return MODE_CLOCK_HIGH;
0268
0269 return MODE_OK;
0270 }
0271
0272 static void
0273 sil164_encoder_mode_set(struct drm_encoder *encoder,
0274 struct drm_display_mode *mode,
0275 struct drm_display_mode *adjusted_mode)
0276 {
0277 struct sil164_priv *priv = to_sil164_priv(encoder);
0278 bool duallink = adjusted_mode->clock > 165000;
0279
0280 sil164_init_state(drm_i2c_encoder_get_client(encoder),
0281 &priv->config, duallink);
0282
0283 if (priv->duallink_slave)
0284 sil164_init_state(priv->duallink_slave,
0285 &priv->config, duallink);
0286
0287 sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
0288 }
0289
0290 static enum drm_connector_status
0291 sil164_encoder_detect(struct drm_encoder *encoder,
0292 struct drm_connector *connector)
0293 {
0294 struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
0295
0296 if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT)
0297 return connector_status_connected;
0298 else
0299 return connector_status_disconnected;
0300 }
0301
0302 static int
0303 sil164_encoder_get_modes(struct drm_encoder *encoder,
0304 struct drm_connector *connector)
0305 {
0306 return 0;
0307 }
0308
0309 static int
0310 sil164_encoder_create_resources(struct drm_encoder *encoder,
0311 struct drm_connector *connector)
0312 {
0313 return 0;
0314 }
0315
0316 static int
0317 sil164_encoder_set_property(struct drm_encoder *encoder,
0318 struct drm_connector *connector,
0319 struct drm_property *property,
0320 uint64_t val)
0321 {
0322 return 0;
0323 }
0324
0325 static void
0326 sil164_encoder_destroy(struct drm_encoder *encoder)
0327 {
0328 struct sil164_priv *priv = to_sil164_priv(encoder);
0329
0330 i2c_unregister_device(priv->duallink_slave);
0331
0332 kfree(priv);
0333 drm_i2c_encoder_destroy(encoder);
0334 }
0335
0336 static const struct drm_encoder_slave_funcs sil164_encoder_funcs = {
0337 .set_config = sil164_encoder_set_config,
0338 .destroy = sil164_encoder_destroy,
0339 .dpms = sil164_encoder_dpms,
0340 .save = sil164_encoder_save,
0341 .restore = sil164_encoder_restore,
0342 .mode_valid = sil164_encoder_mode_valid,
0343 .mode_set = sil164_encoder_mode_set,
0344 .detect = sil164_encoder_detect,
0345 .get_modes = sil164_encoder_get_modes,
0346 .create_resources = sil164_encoder_create_resources,
0347 .set_property = sil164_encoder_set_property,
0348 };
0349
0350
0351
0352 static int
0353 sil164_probe(struct i2c_client *client, const struct i2c_device_id *id)
0354 {
0355 int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 |
0356 sil164_read(client, SIL164_VENDOR_LO);
0357 int device = sil164_read(client, SIL164_DEVICE_HI) << 8 |
0358 sil164_read(client, SIL164_DEVICE_LO);
0359 int rev = sil164_read(client, SIL164_REVISION);
0360
0361 if (vendor != 0x1 || device != 0x6) {
0362 sil164_dbg(client, "Unknown device %x:%x.%x\n",
0363 vendor, device, rev);
0364 return -ENODEV;
0365 }
0366
0367 sil164_info(client, "Detected device %x:%x.%x\n",
0368 vendor, device, rev);
0369
0370 return 0;
0371 }
0372
0373 static int
0374 sil164_remove(struct i2c_client *client)
0375 {
0376 return 0;
0377 }
0378
0379 static struct i2c_client *
0380 sil164_detect_slave(struct i2c_client *client)
0381 {
0382 struct i2c_adapter *adap = client->adapter;
0383 struct i2c_msg msg = {
0384 .addr = SIL164_I2C_ADDR_SLAVE,
0385 .len = 0,
0386 };
0387 const struct i2c_board_info info = {
0388 I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE)
0389 };
0390
0391 if (i2c_transfer(adap, &msg, 1) != 1) {
0392 sil164_dbg(adap, "No dual-link slave found.");
0393 return NULL;
0394 }
0395
0396 return i2c_new_client_device(adap, &info);
0397 }
0398
0399 static int
0400 sil164_encoder_init(struct i2c_client *client,
0401 struct drm_device *dev,
0402 struct drm_encoder_slave *encoder)
0403 {
0404 struct sil164_priv *priv;
0405 struct i2c_client *slave_client;
0406
0407 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0408 if (!priv)
0409 return -ENOMEM;
0410
0411 encoder->slave_priv = priv;
0412 encoder->slave_funcs = &sil164_encoder_funcs;
0413
0414 slave_client = sil164_detect_slave(client);
0415 if (!IS_ERR(slave_client))
0416 priv->duallink_slave = slave_client;
0417
0418 return 0;
0419 }
0420
0421 static const struct i2c_device_id sil164_ids[] = {
0422 { "sil164", 0 },
0423 { }
0424 };
0425 MODULE_DEVICE_TABLE(i2c, sil164_ids);
0426
0427 static struct drm_i2c_encoder_driver sil164_driver = {
0428 .i2c_driver = {
0429 .probe = sil164_probe,
0430 .remove = sil164_remove,
0431 .driver = {
0432 .name = "sil164",
0433 },
0434 .id_table = sil164_ids,
0435 },
0436 .encoder_init = sil164_encoder_init,
0437 };
0438
0439
0440
0441 static int __init
0442 sil164_init(void)
0443 {
0444 return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver);
0445 }
0446
0447 static void __exit
0448 sil164_exit(void)
0449 {
0450 drm_i2c_encoder_unregister(&sil164_driver);
0451 }
0452
0453 MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>");
0454 MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver");
0455 MODULE_LICENSE("GPL and additional rights");
0456
0457 module_init(sil164_init);
0458 module_exit(sil164_exit);