1 /* 2 * Copyright (C) 2010 Francisco Jerez. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27 #include <linux/module.h> 28 29 #include <drm/drm_drv.h> 30 #include <drm/drm_encoder_slave.h> 31 #include <drm/drm_print.h> 32 #include <drm/drm_probe_helper.h> 33 #include <drm/i2c/sil164.h> 34 35 struct sil164_priv { 36 struct sil164_encoder_params config; 37 struct i2c_client *duallink_slave; 38 39 uint8_t saved_state[0x10]; 40 uint8_t saved_slave_state[0x10]; 41 }; 42 43 #define to_sil164_priv(x) \ 44 ((struct sil164_priv *)to_encoder_slave(x)->slave_priv) 45 46 #define sil164_dbg(client, format, ...) do { \ 47 if (drm_debug_enabled(DRM_UT_KMS)) \ 48 dev_printk(KERN_DEBUG, &client->dev, \ 49 "%s: " format, __func__, ## __VA_ARGS__); \ 50 } while (0) 51 #define sil164_info(client, format, ...) \ 52 dev_info(&client->dev, format, __VA_ARGS__) 53 #define sil164_err(client, format, ...) \ 54 dev_err(&client->dev, format, __VA_ARGS__) 55 56 #define SIL164_I2C_ADDR_MASTER 0x38 57 #define SIL164_I2C_ADDR_SLAVE 0x39 58 59 /* HW register definitions */ 60 61 #define SIL164_VENDOR_LO 0x0 62 #define SIL164_VENDOR_HI 0x1 63 #define SIL164_DEVICE_LO 0x2 64 #define SIL164_DEVICE_HI 0x3 65 #define SIL164_REVISION 0x4 66 #define SIL164_FREQ_MIN 0x6 67 #define SIL164_FREQ_MAX 0x7 68 #define SIL164_CONTROL0 0x8 69 # define SIL164_CONTROL0_POWER_ON 0x01 70 # define SIL164_CONTROL0_EDGE_RISING 0x02 71 # define SIL164_CONTROL0_INPUT_24BIT 0x04 72 # define SIL164_CONTROL0_DUAL_EDGE 0x08 73 # define SIL164_CONTROL0_HSYNC_ON 0x10 74 # define SIL164_CONTROL0_VSYNC_ON 0x20 75 #define SIL164_DETECT 0x9 76 # define SIL164_DETECT_INTR_STAT 0x01 77 # define SIL164_DETECT_HOTPLUG_STAT 0x02 78 # define SIL164_DETECT_RECEIVER_STAT 0x04 79 # define SIL164_DETECT_INTR_MODE_RECEIVER 0x00 80 # define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08 81 # define SIL164_DETECT_OUT_MODE_HIGH 0x00 82 # define SIL164_DETECT_OUT_MODE_INTR 0x10 83 # define SIL164_DETECT_OUT_MODE_RECEIVER 0x20 84 # define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30 85 # define SIL164_DETECT_VSWING_STAT 0x80 86 #define SIL164_CONTROL1 0xa 87 # define SIL164_CONTROL1_DESKEW_ENABLE 0x10 88 # define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5 89 #define SIL164_GPIO 0xb 90 #define SIL164_CONTROL2 0xc 91 # define SIL164_CONTROL2_FILTER_ENABLE 0x01 92 # define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1 93 # define SIL164_CONTROL2_DUALLINK_MASTER 0x40 94 # define SIL164_CONTROL2_SYNC_CONT 0x80 95 #define SIL164_DUALLINK 0xd 96 # define SIL164_DUALLINK_ENABLE 0x10 97 # define SIL164_DUALLINK_SKEW_SHIFT 5 98 #define SIL164_PLLZONE 0xe 99 # define SIL164_PLLZONE_STAT 0x08 100 # define SIL164_PLLZONE_FORCE_ON 0x10 101 # define SIL164_PLLZONE_FORCE_HIGH 0x20 102 103 /* HW access functions */ 104 105 static void 106 sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val) 107 { 108 uint8_t buf[] = {addr, val}; 109 int ret; 110 111 ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 112 if (ret < 0) 113 sil164_err(client, "Error %d writing to subaddress 0x%x\n", 114 ret, addr); 115 } 116 117 static uint8_t 118 sil164_read(struct i2c_client *client, uint8_t addr) 119 { 120 uint8_t val; 121 int ret; 122 123 ret = i2c_master_send(client, &addr, sizeof(addr)); 124 if (ret < 0) 125 goto fail; 126 127 ret = i2c_master_recv(client, &val, sizeof(val)); 128 if (ret < 0) 129 goto fail; 130 131 return val; 132 133 fail: 134 sil164_err(client, "Error %d reading from subaddress 0x%x\n", 135 ret, addr); 136 return 0; 137 } 138 139 static void 140 sil164_save_state(struct i2c_client *client, uint8_t *state) 141 { 142 int i; 143 144 for (i = 0x8; i <= 0xe; i++) 145 state[i] = sil164_read(client, i); 146 } 147 148 static void 149 sil164_restore_state(struct i2c_client *client, uint8_t *state) 150 { 151 int i; 152 153 for (i = 0x8; i <= 0xe; i++) 154 sil164_write(client, i, state[i]); 155 } 156 157 static void 158 sil164_set_power_state(struct i2c_client *client, bool on) 159 { 160 uint8_t control0 = sil164_read(client, SIL164_CONTROL0); 161 162 if (on) 163 control0 |= SIL164_CONTROL0_POWER_ON; 164 else 165 control0 &= ~SIL164_CONTROL0_POWER_ON; 166 167 sil164_write(client, SIL164_CONTROL0, control0); 168 } 169 170 static void 171 sil164_init_state(struct i2c_client *client, 172 struct sil164_encoder_params *config, 173 bool duallink) 174 { 175 sil164_write(client, SIL164_CONTROL0, 176 SIL164_CONTROL0_HSYNC_ON | 177 SIL164_CONTROL0_VSYNC_ON | 178 (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) | 179 (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) | 180 (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0)); 181 182 sil164_write(client, SIL164_DETECT, 183 SIL164_DETECT_INTR_STAT | 184 SIL164_DETECT_OUT_MODE_RECEIVER); 185 186 sil164_write(client, SIL164_CONTROL1, 187 (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) | 188 (((config->input_skew + 4) & 0x7) 189 << SIL164_CONTROL1_DESKEW_INCR_SHIFT)); 190 191 sil164_write(client, SIL164_CONTROL2, 192 SIL164_CONTROL2_SYNC_CONT | 193 (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) | 194 (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT)); 195 196 sil164_write(client, SIL164_PLLZONE, 0); 197 198 if (duallink) 199 sil164_write(client, SIL164_DUALLINK, 200 SIL164_DUALLINK_ENABLE | 201 (((config->duallink_skew + 4) & 0x7) 202 << SIL164_DUALLINK_SKEW_SHIFT)); 203 else 204 sil164_write(client, SIL164_DUALLINK, 0); 205 } 206 207 /* DRM encoder functions */ 208 209 static void 210 sil164_encoder_set_config(struct drm_encoder *encoder, void *params) 211 { 212 struct sil164_priv *priv = to_sil164_priv(encoder); 213 214 priv->config = *(struct sil164_encoder_params *)params; 215 } 216 217 static void 218 sil164_encoder_dpms(struct drm_encoder *encoder, int mode) 219 { 220 struct sil164_priv *priv = to_sil164_priv(encoder); 221 bool on = (mode == DRM_MODE_DPMS_ON); 222 bool duallink = (on && encoder->crtc->mode.clock > 165000); 223 224 sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on); 225 226 if (priv->duallink_slave) 227 sil164_set_power_state(priv->duallink_slave, duallink); 228 } 229 230 static void 231 sil164_encoder_save(struct drm_encoder *encoder) 232 { 233 struct sil164_priv *priv = to_sil164_priv(encoder); 234 235 sil164_save_state(drm_i2c_encoder_get_client(encoder), 236 priv->saved_state); 237 238 if (priv->duallink_slave) 239 sil164_save_state(priv->duallink_slave, 240 priv->saved_slave_state); 241 } 242 243 static void 244 sil164_encoder_restore(struct drm_encoder *encoder) 245 { 246 struct sil164_priv *priv = to_sil164_priv(encoder); 247 248 sil164_restore_state(drm_i2c_encoder_get_client(encoder), 249 priv->saved_state); 250 251 if (priv->duallink_slave) 252 sil164_restore_state(priv->duallink_slave, 253 priv->saved_slave_state); 254 } 255 256 static int 257 sil164_encoder_mode_valid(struct drm_encoder *encoder, 258 struct drm_display_mode *mode) 259 { 260 struct sil164_priv *priv = to_sil164_priv(encoder); 261 262 if (mode->clock < 32000) 263 return MODE_CLOCK_LOW; 264 265 if (mode->clock > 330000 || 266 (mode->clock > 165000 && !priv->duallink_slave)) 267 return MODE_CLOCK_HIGH; 268 269 return MODE_OK; 270 } 271 272 static void 273 sil164_encoder_mode_set(struct drm_encoder *encoder, 274 struct drm_display_mode *mode, 275 struct drm_display_mode *adjusted_mode) 276 { 277 struct sil164_priv *priv = to_sil164_priv(encoder); 278 bool duallink = adjusted_mode->clock > 165000; 279 280 sil164_init_state(drm_i2c_encoder_get_client(encoder), 281 &priv->config, duallink); 282 283 if (priv->duallink_slave) 284 sil164_init_state(priv->duallink_slave, 285 &priv->config, duallink); 286 287 sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON); 288 } 289 290 static enum drm_connector_status 291 sil164_encoder_detect(struct drm_encoder *encoder, 292 struct drm_connector *connector) 293 { 294 struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 295 296 if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT) 297 return connector_status_connected; 298 else 299 return connector_status_disconnected; 300 } 301 302 static int 303 sil164_encoder_get_modes(struct drm_encoder *encoder, 304 struct drm_connector *connector) 305 { 306 return 0; 307 } 308 309 static int 310 sil164_encoder_create_resources(struct drm_encoder *encoder, 311 struct drm_connector *connector) 312 { 313 return 0; 314 } 315 316 static int 317 sil164_encoder_set_property(struct drm_encoder *encoder, 318 struct drm_connector *connector, 319 struct drm_property *property, 320 uint64_t val) 321 { 322 return 0; 323 } 324 325 static void 326 sil164_encoder_destroy(struct drm_encoder *encoder) 327 { 328 struct sil164_priv *priv = to_sil164_priv(encoder); 329 330 i2c_unregister_device(priv->duallink_slave); 331 332 kfree(priv); 333 drm_i2c_encoder_destroy(encoder); 334 } 335 336 static const struct drm_encoder_slave_funcs sil164_encoder_funcs = { 337 .set_config = sil164_encoder_set_config, 338 .destroy = sil164_encoder_destroy, 339 .dpms = sil164_encoder_dpms, 340 .save = sil164_encoder_save, 341 .restore = sil164_encoder_restore, 342 .mode_valid = sil164_encoder_mode_valid, 343 .mode_set = sil164_encoder_mode_set, 344 .detect = sil164_encoder_detect, 345 .get_modes = sil164_encoder_get_modes, 346 .create_resources = sil164_encoder_create_resources, 347 .set_property = sil164_encoder_set_property, 348 }; 349 350 /* I2C driver functions */ 351 352 static int 353 sil164_probe(struct i2c_client *client, const struct i2c_device_id *id) 354 { 355 int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 | 356 sil164_read(client, SIL164_VENDOR_LO); 357 int device = sil164_read(client, SIL164_DEVICE_HI) << 8 | 358 sil164_read(client, SIL164_DEVICE_LO); 359 int rev = sil164_read(client, SIL164_REVISION); 360 361 if (vendor != 0x1 || device != 0x6) { 362 sil164_dbg(client, "Unknown device %x:%x.%x\n", 363 vendor, device, rev); 364 return -ENODEV; 365 } 366 367 sil164_info(client, "Detected device %x:%x.%x\n", 368 vendor, device, rev); 369 370 return 0; 371 } 372 373 static int 374 sil164_remove(struct i2c_client *client) 375 { 376 return 0; 377 } 378 379 static struct i2c_client * 380 sil164_detect_slave(struct i2c_client *client) 381 { 382 struct i2c_adapter *adap = client->adapter; 383 struct i2c_msg msg = { 384 .addr = SIL164_I2C_ADDR_SLAVE, 385 .len = 0, 386 }; 387 const struct i2c_board_info info = { 388 I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE) 389 }; 390 391 if (i2c_transfer(adap, &msg, 1) != 1) { 392 sil164_dbg(adap, "No dual-link slave found."); 393 return NULL; 394 } 395 396 return i2c_new_device(adap, &info); 397 } 398 399 static int 400 sil164_encoder_init(struct i2c_client *client, 401 struct drm_device *dev, 402 struct drm_encoder_slave *encoder) 403 { 404 struct sil164_priv *priv; 405 406 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 407 if (!priv) 408 return -ENOMEM; 409 410 encoder->slave_priv = priv; 411 encoder->slave_funcs = &sil164_encoder_funcs; 412 413 priv->duallink_slave = sil164_detect_slave(client); 414 415 return 0; 416 } 417 418 static const struct i2c_device_id sil164_ids[] = { 419 { "sil164", 0 }, 420 { } 421 }; 422 MODULE_DEVICE_TABLE(i2c, sil164_ids); 423 424 static struct drm_i2c_encoder_driver sil164_driver = { 425 .i2c_driver = { 426 .probe = sil164_probe, 427 .remove = sil164_remove, 428 .driver = { 429 .name = "sil164", 430 }, 431 .id_table = sil164_ids, 432 }, 433 .encoder_init = sil164_encoder_init, 434 }; 435 436 /* Module initialization */ 437 438 static int __init 439 sil164_init(void) 440 { 441 return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver); 442 } 443 444 static void __exit 445 sil164_exit(void) 446 { 447 drm_i2c_encoder_unregister(&sil164_driver); 448 } 449 450 MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>"); 451 MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver"); 452 MODULE_LICENSE("GPL and additional rights"); 453 454 module_init(sil164_init); 455 module_exit(sil164_exit); 456