LCOV - code coverage report
Current view: top level - dev/pci/drm/i915 - dvo_tfp410.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 109 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2007 Dave Mueller
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice (including the next
      12             :  * paragraph) shall be included in all copies or substantial portions of the
      13             :  * Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      20             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      21             :  * IN THE SOFTWARE.
      22             :  *
      23             :  * Authors:
      24             :  *    Dave Mueller <dave.mueller@gmx.ch>
      25             :  *
      26             :  */
      27             : 
      28             : #include "dvo.h"
      29             : 
      30             : /* register definitions according to the TFP410 data sheet */
      31             : #define TFP410_VID              0x014C
      32             : #define TFP410_DID              0x0410
      33             : 
      34             : #define TFP410_VID_LO           0x00
      35             : #define TFP410_VID_HI           0x01
      36             : #define TFP410_DID_LO           0x02
      37             : #define TFP410_DID_HI           0x03
      38             : #define TFP410_REV              0x04
      39             : 
      40             : #define TFP410_CTL_1            0x08
      41             : #define TFP410_CTL_1_TDIS       (1<<6)
      42             : #define TFP410_CTL_1_VEN        (1<<5)
      43             : #define TFP410_CTL_1_HEN        (1<<4)
      44             : #define TFP410_CTL_1_DSEL       (1<<3)
      45             : #define TFP410_CTL_1_BSEL       (1<<2)
      46             : #define TFP410_CTL_1_EDGE       (1<<1)
      47             : #define TFP410_CTL_1_PD         (1<<0)
      48             : 
      49             : #define TFP410_CTL_2            0x09
      50             : #define TFP410_CTL_2_VLOW       (1<<7)
      51             : #define TFP410_CTL_2_MSEL_MASK  (0x7<<4)
      52             : #define TFP410_CTL_2_MSEL       (1<<4)
      53             : #define TFP410_CTL_2_TSEL       (1<<3)
      54             : #define TFP410_CTL_2_RSEN       (1<<2)
      55             : #define TFP410_CTL_2_HTPLG      (1<<1)
      56             : #define TFP410_CTL_2_MDI        (1<<0)
      57             : 
      58             : #define TFP410_CTL_3            0x0A
      59             : #define TFP410_CTL_3_DK_MASK    (0x7<<5)
      60             : #define TFP410_CTL_3_DK         (1<<5)
      61             : #define TFP410_CTL_3_DKEN       (1<<4)
      62             : #define TFP410_CTL_3_CTL_MASK   (0x7<<1)
      63             : #define TFP410_CTL_3_CTL        (1<<1)
      64             : 
      65             : #define TFP410_USERCFG          0x0B
      66             : 
      67             : #define TFP410_DE_DLY           0x32
      68             : 
      69             : #define TFP410_DE_CTL           0x33
      70             : #define TFP410_DE_CTL_DEGEN     (1<<6)
      71             : #define TFP410_DE_CTL_VSPOL     (1<<5)
      72             : #define TFP410_DE_CTL_HSPOL     (1<<4)
      73             : #define TFP410_DE_CTL_DEDLY8    (1<<0)
      74             : 
      75             : #define TFP410_DE_TOP           0x34
      76             : 
      77             : #define TFP410_DE_CNT_LO        0x36
      78             : #define TFP410_DE_CNT_HI        0x37
      79             : 
      80             : #define TFP410_DE_LIN_LO        0x38
      81             : #define TFP410_DE_LIN_HI        0x39
      82             : 
      83             : #define TFP410_H_RES_LO         0x3A
      84             : #define TFP410_H_RES_HI         0x3B
      85             : 
      86             : #define TFP410_V_RES_LO         0x3C
      87             : #define TFP410_V_RES_HI         0x3D
      88             : 
      89             : struct tfp410_priv {
      90             :         bool quiet;
      91             : };
      92             : 
      93           0 : static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
      94             : {
      95           0 :         struct tfp410_priv *tfp = dvo->dev_priv;
      96           0 :         struct i2c_adapter *adapter = dvo->i2c_bus;
      97           0 :         u8 out_buf[2];
      98           0 :         u8 in_buf[2];
      99             : 
     100           0 :         struct i2c_msg msgs[] = {
     101           0 :                 {
     102           0 :                         .addr = dvo->slave_addr,
     103             :                         .flags = 0,
     104             :                         .len = 1,
     105           0 :                         .buf = out_buf,
     106             :                 },
     107           0 :                 {
     108           0 :                         .addr = dvo->slave_addr,
     109             :                         .flags = I2C_M_RD,
     110             :                         .len = 1,
     111           0 :                         .buf = in_buf,
     112             :                 }
     113             :         };
     114             : 
     115           0 :         out_buf[0] = addr;
     116           0 :         out_buf[1] = 0;
     117             : 
     118           0 :         if (i2c_transfer(adapter, msgs, 2) == 2) {
     119           0 :                 *ch = in_buf[0];
     120           0 :                 return true;
     121             :         }
     122             : 
     123           0 :         if (!tfp->quiet) {
     124             :                 DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
     125             :                           addr, adapter->name, dvo->slave_addr);
     126             :         }
     127           0 :         return false;
     128           0 : }
     129             : 
     130           0 : static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
     131             : {
     132           0 :         struct tfp410_priv *tfp = dvo->dev_priv;
     133           0 :         struct i2c_adapter *adapter = dvo->i2c_bus;
     134           0 :         uint8_t out_buf[2];
     135           0 :         struct i2c_msg msg = {
     136           0 :                 .addr = dvo->slave_addr,
     137             :                 .flags = 0,
     138             :                 .len = 2,
     139           0 :                 .buf = out_buf,
     140             :         };
     141             : 
     142           0 :         out_buf[0] = addr;
     143           0 :         out_buf[1] = ch;
     144             : 
     145           0 :         if (i2c_transfer(adapter, &msg, 1) == 1)
     146           0 :                 return true;
     147             : 
     148           0 :         if (!tfp->quiet) {
     149             :                 DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
     150             :                           addr, adapter->name, dvo->slave_addr);
     151             :         }
     152             : 
     153           0 :         return false;
     154           0 : }
     155             : 
     156           0 : static int tfp410_getid(struct intel_dvo_device *dvo, int addr)
     157             : {
     158           0 :         uint8_t ch1, ch2;
     159             : 
     160           0 :         if (tfp410_readb(dvo, addr+0, &ch1) &&
     161           0 :             tfp410_readb(dvo, addr+1, &ch2))
     162           0 :                 return ((ch2 << 8) & 0xFF00) | (ch1 & 0x00FF);
     163             : 
     164           0 :         return -1;
     165           0 : }
     166             : 
     167             : /* Ti TFP410 driver for chip on i2c bus */
     168           0 : static bool tfp410_init(struct intel_dvo_device *dvo,
     169             :                         struct i2c_adapter *adapter)
     170             : {
     171             :         /* this will detect the tfp410 chip on the specified i2c bus */
     172             :         struct tfp410_priv *tfp;
     173             :         int id;
     174             : 
     175           0 :         tfp = kzalloc(sizeof(struct tfp410_priv), GFP_KERNEL);
     176           0 :         if (tfp == NULL)
     177           0 :                 return false;
     178             : 
     179           0 :         dvo->i2c_bus = adapter;
     180           0 :         dvo->dev_priv = tfp;
     181           0 :         tfp->quiet = true;
     182             : 
     183           0 :         if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
     184             :                 DRM_DEBUG_KMS("tfp410 not detected got VID %X: from %s "
     185             :                                 "Slave %d.\n",
     186             :                           id, adapter->name, dvo->slave_addr);
     187             :                 goto out;
     188             :         }
     189             : 
     190           0 :         if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
     191             :                 DRM_DEBUG_KMS("tfp410 not detected got DID %X: from %s "
     192             :                                 "Slave %d.\n",
     193             :                           id, adapter->name, dvo->slave_addr);
     194             :                 goto out;
     195             :         }
     196           0 :         tfp->quiet = false;
     197           0 :         return true;
     198             : out:
     199           0 :         kfree(tfp);
     200           0 :         return false;
     201           0 : }
     202             : 
     203           0 : static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo)
     204             : {
     205             :         enum drm_connector_status ret = connector_status_disconnected;
     206           0 :         uint8_t ctl2;
     207             : 
     208           0 :         if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) {
     209           0 :                 if (ctl2 & TFP410_CTL_2_RSEN)
     210           0 :                         ret = connector_status_connected;
     211             :                 else
     212             :                         ret = connector_status_disconnected;
     213             :         }
     214             : 
     215           0 :         return ret;
     216           0 : }
     217             : 
     218           0 : static enum drm_mode_status tfp410_mode_valid(struct intel_dvo_device *dvo,
     219             :                                               struct drm_display_mode *mode)
     220             : {
     221           0 :         return MODE_OK;
     222             : }
     223             : 
     224           0 : static void tfp410_mode_set(struct intel_dvo_device *dvo,
     225             :                             const struct drm_display_mode *mode,
     226             :                             const struct drm_display_mode *adjusted_mode)
     227             : {
     228             :         /* As long as the basics are set up, since we don't have clock dependencies
     229             :         * in the mode setup, we can just leave the registers alone and everything
     230             :         * will work fine.
     231             :         */
     232             :         /* don't do much */
     233           0 :         return;
     234             : }
     235             : 
     236             : /* set the tfp410 power state */
     237           0 : static void tfp410_dpms(struct intel_dvo_device *dvo, bool enable)
     238             : {
     239           0 :         uint8_t ctl1;
     240             : 
     241           0 :         if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
     242           0 :                 return;
     243             : 
     244           0 :         if (enable)
     245           0 :                 ctl1 |= TFP410_CTL_1_PD;
     246             :         else
     247           0 :                 ctl1 &= ~TFP410_CTL_1_PD;
     248             : 
     249           0 :         tfp410_writeb(dvo, TFP410_CTL_1, ctl1);
     250           0 : }
     251             : 
     252           0 : static bool tfp410_get_hw_state(struct intel_dvo_device *dvo)
     253             : {
     254           0 :         uint8_t ctl1;
     255             : 
     256           0 :         if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
     257           0 :                 return false;
     258             : 
     259           0 :         if (ctl1 & TFP410_CTL_1_PD)
     260           0 :                 return true;
     261             :         else
     262           0 :                 return false;
     263           0 : }
     264             : 
     265           0 : static void tfp410_dump_regs(struct intel_dvo_device *dvo)
     266             : {
     267           0 :         uint8_t val, val2;
     268             : 
     269           0 :         tfp410_readb(dvo, TFP410_REV, &val);
     270             :         DRM_DEBUG_KMS("TFP410_REV: 0x%02X\n", val);
     271           0 :         tfp410_readb(dvo, TFP410_CTL_1, &val);
     272             :         DRM_DEBUG_KMS("TFP410_CTL1: 0x%02X\n", val);
     273           0 :         tfp410_readb(dvo, TFP410_CTL_2, &val);
     274             :         DRM_DEBUG_KMS("TFP410_CTL2: 0x%02X\n", val);
     275           0 :         tfp410_readb(dvo, TFP410_CTL_3, &val);
     276             :         DRM_DEBUG_KMS("TFP410_CTL3: 0x%02X\n", val);
     277           0 :         tfp410_readb(dvo, TFP410_USERCFG, &val);
     278             :         DRM_DEBUG_KMS("TFP410_USERCFG: 0x%02X\n", val);
     279           0 :         tfp410_readb(dvo, TFP410_DE_DLY, &val);
     280             :         DRM_DEBUG_KMS("TFP410_DE_DLY: 0x%02X\n", val);
     281           0 :         tfp410_readb(dvo, TFP410_DE_CTL, &val);
     282             :         DRM_DEBUG_KMS("TFP410_DE_CTL: 0x%02X\n", val);
     283           0 :         tfp410_readb(dvo, TFP410_DE_TOP, &val);
     284             :         DRM_DEBUG_KMS("TFP410_DE_TOP: 0x%02X\n", val);
     285           0 :         tfp410_readb(dvo, TFP410_DE_CNT_LO, &val);
     286           0 :         tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2);
     287             :         DRM_DEBUG_KMS("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
     288           0 :         tfp410_readb(dvo, TFP410_DE_LIN_LO, &val);
     289           0 :         tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2);
     290             :         DRM_DEBUG_KMS("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
     291           0 :         tfp410_readb(dvo, TFP410_H_RES_LO, &val);
     292           0 :         tfp410_readb(dvo, TFP410_H_RES_HI, &val2);
     293             :         DRM_DEBUG_KMS("TFP410_H_RES: 0x%02X%02X\n", val2, val);
     294           0 :         tfp410_readb(dvo, TFP410_V_RES_LO, &val);
     295           0 :         tfp410_readb(dvo, TFP410_V_RES_HI, &val2);
     296             :         DRM_DEBUG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val);
     297           0 : }
     298             : 
     299           0 : static void tfp410_destroy(struct intel_dvo_device *dvo)
     300             : {
     301           0 :         struct tfp410_priv *tfp = dvo->dev_priv;
     302             : 
     303           0 :         if (tfp) {
     304           0 :                 kfree(tfp);
     305           0 :                 dvo->dev_priv = NULL;
     306           0 :         }
     307           0 : }
     308             : 
     309             : struct intel_dvo_dev_ops tfp410_ops = {
     310             :         .init = tfp410_init,
     311             :         .detect = tfp410_detect,
     312             :         .mode_valid = tfp410_mode_valid,
     313             :         .mode_set = tfp410_mode_set,
     314             :         .dpms = tfp410_dpms,
     315             :         .get_hw_state = tfp410_get_hw_state,
     316             :         .dump_regs = tfp410_dump_regs,
     317             :         .destroy = tfp410_destroy,
     318             : };

Generated by: LCOV version 1.13