root/drivers/video/fbdev/aty/radeon_i2c.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. radeon_gpio_setscl
  2. radeon_gpio_setsda
  3. radeon_gpio_getscl
  4. radeon_gpio_getsda
  5. radeon_setup_i2c_bus
  6. radeon_create_i2c_busses
  7. radeon_delete_i2c_busses
  8. radeon_probe_i2c_connector

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include "radeonfb.h"
   3 
   4 #include <linux/module.h>
   5 #include <linux/kernel.h>
   6 #include <linux/delay.h>
   7 #include <linux/fb.h>
   8 
   9 
  10 #include <linux/i2c.h>
  11 #include <linux/i2c-algo-bit.h>
  12 
  13 #include <asm/io.h>
  14 
  15 #include <video/radeon.h>
  16 #include "../edid.h"
  17 
  18 static void radeon_gpio_setscl(void* data, int state)
  19 {
  20         struct radeon_i2c_chan  *chan = data;
  21         struct radeonfb_info    *rinfo = chan->rinfo;
  22         u32                     val;
  23         
  24         val = INREG(chan->ddc_reg) & ~(VGA_DDC_CLK_OUT_EN);
  25         if (!state)
  26                 val |= VGA_DDC_CLK_OUT_EN;
  27 
  28         OUTREG(chan->ddc_reg, val);
  29         (void)INREG(chan->ddc_reg);
  30 }
  31 
  32 static void radeon_gpio_setsda(void* data, int state)
  33 {
  34         struct radeon_i2c_chan  *chan = data;
  35         struct radeonfb_info    *rinfo = chan->rinfo;
  36         u32                     val;
  37         
  38         val = INREG(chan->ddc_reg) & ~(VGA_DDC_DATA_OUT_EN);
  39         if (!state)
  40                 val |= VGA_DDC_DATA_OUT_EN;
  41 
  42         OUTREG(chan->ddc_reg, val);
  43         (void)INREG(chan->ddc_reg);
  44 }
  45 
  46 static int radeon_gpio_getscl(void* data)
  47 {
  48         struct radeon_i2c_chan  *chan = data;
  49         struct radeonfb_info    *rinfo = chan->rinfo;
  50         u32                     val;
  51         
  52         val = INREG(chan->ddc_reg);
  53 
  54         return (val & VGA_DDC_CLK_INPUT) ? 1 : 0;
  55 }
  56 
  57 static int radeon_gpio_getsda(void* data)
  58 {
  59         struct radeon_i2c_chan  *chan = data;
  60         struct radeonfb_info    *rinfo = chan->rinfo;
  61         u32                     val;
  62         
  63         val = INREG(chan->ddc_reg);
  64 
  65         return (val & VGA_DDC_DATA_INPUT) ? 1 : 0;
  66 }
  67 
  68 static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name)
  69 {
  70         int rc;
  71 
  72         snprintf(chan->adapter.name, sizeof(chan->adapter.name),
  73                  "radeonfb %s", name);
  74         chan->adapter.owner             = THIS_MODULE;
  75         chan->adapter.algo_data         = &chan->algo;
  76         chan->adapter.dev.parent        = &chan->rinfo->pdev->dev;
  77         chan->algo.setsda               = radeon_gpio_setsda;
  78         chan->algo.setscl               = radeon_gpio_setscl;
  79         chan->algo.getsda               = radeon_gpio_getsda;
  80         chan->algo.getscl               = radeon_gpio_getscl;
  81         chan->algo.udelay               = 10;
  82         chan->algo.timeout              = 20;
  83         chan->algo.data                 = chan; 
  84         
  85         i2c_set_adapdata(&chan->adapter, chan);
  86         
  87         /* Raise SCL and SDA */
  88         radeon_gpio_setsda(chan, 1);
  89         radeon_gpio_setscl(chan, 1);
  90         udelay(20);
  91 
  92         rc = i2c_bit_add_bus(&chan->adapter);
  93         if (rc == 0)
  94                 dev_dbg(&chan->rinfo->pdev->dev, "I2C bus %s registered.\n", name);
  95         else
  96                 dev_warn(&chan->rinfo->pdev->dev, "Failed to register I2C bus %s.\n", name);
  97         return rc;
  98 }
  99 
 100 void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
 101 {
 102         rinfo->i2c[0].rinfo     = rinfo;
 103         rinfo->i2c[0].ddc_reg   = GPIO_MONID;
 104 #ifndef CONFIG_PPC
 105         rinfo->i2c[0].adapter.class = I2C_CLASS_HWMON;
 106 #endif
 107         radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
 108 
 109         rinfo->i2c[1].rinfo     = rinfo;
 110         rinfo->i2c[1].ddc_reg   = GPIO_DVI_DDC;
 111         radeon_setup_i2c_bus(&rinfo->i2c[1], "dvi");
 112 
 113         rinfo->i2c[2].rinfo     = rinfo;
 114         rinfo->i2c[2].ddc_reg   = GPIO_VGA_DDC;
 115         radeon_setup_i2c_bus(&rinfo->i2c[2], "vga");
 116 
 117         rinfo->i2c[3].rinfo     = rinfo;
 118         rinfo->i2c[3].ddc_reg   = GPIO_CRT2_DDC;
 119         radeon_setup_i2c_bus(&rinfo->i2c[3], "crt2");
 120 }
 121 
 122 void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
 123 {
 124         if (rinfo->i2c[0].rinfo)
 125                 i2c_del_adapter(&rinfo->i2c[0].adapter);
 126         rinfo->i2c[0].rinfo = NULL;
 127 
 128         if (rinfo->i2c[1].rinfo)
 129                 i2c_del_adapter(&rinfo->i2c[1].adapter);
 130         rinfo->i2c[1].rinfo = NULL;
 131 
 132         if (rinfo->i2c[2].rinfo)
 133                 i2c_del_adapter(&rinfo->i2c[2].adapter);
 134         rinfo->i2c[2].rinfo = NULL;
 135 
 136         if (rinfo->i2c[3].rinfo)
 137                 i2c_del_adapter(&rinfo->i2c[3].adapter);
 138         rinfo->i2c[3].rinfo = NULL;
 139 }
 140 
 141 int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
 142                                u8 **out_edid)
 143 {
 144         u8 *edid;
 145 
 146         edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
 147 
 148         if (out_edid)
 149                 *out_edid = edid;
 150         if (!edid) {
 151                 pr_debug("radeonfb: I2C (port %d) ... not found\n", conn);
 152                 return MT_NONE;
 153         }
 154         if (edid[0x14] & 0x80) {
 155                 /* Fix detection using BIOS tables */
 156                 if (rinfo->is_mobility /*&& conn == ddc_dvi*/ &&
 157                     (INREG(LVDS_GEN_CNTL) & LVDS_ON)) {
 158                         pr_debug("radeonfb: I2C (port %d) ... found LVDS panel\n", conn);
 159                         return MT_LCD;
 160                 } else {
 161                         pr_debug("radeonfb: I2C (port %d) ... found TMDS panel\n", conn);
 162                         return MT_DFP;
 163                 }
 164         }
 165         pr_debug("radeonfb: I2C (port %d) ... found CRT display\n", conn);
 166         return MT_CRT;
 167 }
 168 

/* [<][>][^][v][top][bottom][index][help] */