Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright © 2010 Intel Corporation
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0021  * DEALINGS IN THE SOFTWARE.
0022  *
0023  * Authors:
0024  *  Li Peng <peng.li@intel.com>
0025  */
0026 
0027 #include <linux/export.h>
0028 #include <linux/mutex.h>
0029 #include <linux/pci.h>
0030 #include <linux/i2c.h>
0031 #include <linux/interrupt.h>
0032 #include <linux/delay.h>
0033 #include "psb_drv.h"
0034 
0035 #define HDMI_READ(reg)      readl(hdmi_dev->regs + (reg))
0036 #define HDMI_WRITE(reg, val)    writel(val, hdmi_dev->regs + (reg))
0037 
0038 #define HDMI_HCR    0x1000
0039 #define HCR_DETECT_HDP      (1 << 6)
0040 #define HCR_ENABLE_HDCP     (1 << 5)
0041 #define HCR_ENABLE_AUDIO    (1 << 2)
0042 #define HCR_ENABLE_PIXEL    (1 << 1)
0043 #define HCR_ENABLE_TMDS     (1 << 0)
0044 #define HDMI_HICR   0x1004
0045 #define HDMI_INTR_I2C_ERROR (1 << 4)
0046 #define HDMI_INTR_I2C_FULL  (1 << 3)
0047 #define HDMI_INTR_I2C_DONE  (1 << 2)
0048 #define HDMI_INTR_HPD       (1 << 0)
0049 #define HDMI_HSR    0x1008
0050 #define HDMI_HISR   0x100C
0051 #define HDMI_HI2CRDB0   0x1200
0052 #define HDMI_HI2CHCR    0x1240
0053 #define HI2C_HDCP_WRITE     (0 << 2)
0054 #define HI2C_HDCP_RI_READ   (1 << 2)
0055 #define HI2C_HDCP_READ      (2 << 2)
0056 #define HI2C_EDID_READ      (3 << 2)
0057 #define HI2C_READ_CONTINUE  (1 << 1)
0058 #define HI2C_ENABLE_TRANSACTION (1 << 0)
0059 
0060 #define HDMI_ICRH   0x1100
0061 #define HDMI_HI2CTDR0   0x1244
0062 #define HDMI_HI2CTDR1   0x1248
0063 
0064 #define I2C_STAT_INIT       0
0065 #define I2C_READ_DONE       1
0066 #define I2C_TRANSACTION_DONE    2
0067 
0068 struct hdmi_i2c_dev {
0069     struct i2c_adapter *adap;
0070     struct mutex i2c_lock;
0071     struct completion complete;
0072     int status;
0073     struct i2c_msg *msg;
0074     int buf_offset;
0075 };
0076 
0077 static void hdmi_i2c_irq_enable(struct oaktrail_hdmi_dev *hdmi_dev)
0078 {
0079     u32 temp;
0080 
0081     temp = HDMI_READ(HDMI_HICR);
0082     temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE);
0083     HDMI_WRITE(HDMI_HICR, temp);
0084     HDMI_READ(HDMI_HICR);
0085 }
0086 
0087 static void hdmi_i2c_irq_disable(struct oaktrail_hdmi_dev *hdmi_dev)
0088 {
0089     HDMI_WRITE(HDMI_HICR, 0x0);
0090     HDMI_READ(HDMI_HICR);
0091 }
0092 
0093 static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
0094 {
0095     struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
0096     struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
0097     u32 temp;
0098 
0099     i2c_dev->status = I2C_STAT_INIT;
0100     i2c_dev->msg = pmsg;
0101     i2c_dev->buf_offset = 0;
0102     reinit_completion(&i2c_dev->complete);
0103 
0104     /* Enable I2C transaction */
0105     temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION;
0106     HDMI_WRITE(HDMI_HI2CHCR, temp);
0107     HDMI_READ(HDMI_HI2CHCR);
0108 
0109     while (i2c_dev->status != I2C_TRANSACTION_DONE)
0110         wait_for_completion_interruptible_timeout(&i2c_dev->complete,
0111                                 10 * HZ);
0112 
0113     return 0;
0114 }
0115 
0116 static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg)
0117 {
0118     /*
0119      * XXX: i2c write seems isn't useful for EDID probe, don't do anything
0120      */
0121     return 0;
0122 }
0123 
0124 static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,
0125                 struct i2c_msg *pmsg,
0126                 int num)
0127 {
0128     struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
0129     struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
0130     int i;
0131 
0132     mutex_lock(&i2c_dev->i2c_lock);
0133 
0134     /* Enable i2c unit */
0135     HDMI_WRITE(HDMI_ICRH, 0x00008760);
0136 
0137     /* Enable irq */
0138     hdmi_i2c_irq_enable(hdmi_dev);
0139     for (i = 0; i < num; i++) {
0140         if (pmsg->len && pmsg->buf) {
0141             if (pmsg->flags & I2C_M_RD)
0142                 xfer_read(adap, pmsg);
0143             else
0144                 xfer_write(adap, pmsg);
0145         }
0146         pmsg++;         /* next message */
0147     }
0148 
0149     /* Disable irq */
0150     hdmi_i2c_irq_disable(hdmi_dev);
0151 
0152     mutex_unlock(&i2c_dev->i2c_lock);
0153 
0154     return i;
0155 }
0156 
0157 static u32 oaktrail_hdmi_i2c_func(struct i2c_adapter *adapter)
0158 {
0159     return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
0160 }
0161 
0162 static const struct i2c_algorithm oaktrail_hdmi_i2c_algorithm = {
0163     .master_xfer    = oaktrail_hdmi_i2c_access,
0164     .functionality  = oaktrail_hdmi_i2c_func,
0165 };
0166 
0167 static struct i2c_adapter oaktrail_hdmi_i2c_adapter = {
0168     .name       = "oaktrail_hdmi_i2c",
0169     .nr     = 3,
0170     .owner      = THIS_MODULE,
0171     .class      = I2C_CLASS_DDC,
0172     .algo       = &oaktrail_hdmi_i2c_algorithm,
0173 };
0174 
0175 static void hdmi_i2c_read(struct oaktrail_hdmi_dev *hdmi_dev)
0176 {
0177     struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
0178     struct i2c_msg *msg = i2c_dev->msg;
0179     u8 *buf = msg->buf;
0180     u32 temp;
0181     int i, offset;
0182 
0183     offset = i2c_dev->buf_offset;
0184     for (i = 0; i < 0x10; i++) {
0185         temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4));
0186         memcpy(buf + (offset + i * 4), &temp, 4);
0187     }
0188     i2c_dev->buf_offset += (0x10 * 4);
0189 
0190     /* clearing read buffer full intr */
0191     temp = HDMI_READ(HDMI_HISR);
0192     HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL);
0193     HDMI_READ(HDMI_HISR);
0194 
0195     /* continue read transaction */
0196     temp = HDMI_READ(HDMI_HI2CHCR);
0197     HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE);
0198     HDMI_READ(HDMI_HI2CHCR);
0199 
0200     i2c_dev->status = I2C_READ_DONE;
0201     return;
0202 }
0203 
0204 static void hdmi_i2c_transaction_done(struct oaktrail_hdmi_dev *hdmi_dev)
0205 {
0206     struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
0207     u32 temp;
0208 
0209     /* clear transaction done intr */
0210     temp = HDMI_READ(HDMI_HISR);
0211     HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE);
0212     HDMI_READ(HDMI_HISR);
0213 
0214 
0215     temp = HDMI_READ(HDMI_HI2CHCR);
0216     HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION);
0217     HDMI_READ(HDMI_HI2CHCR);
0218 
0219     i2c_dev->status = I2C_TRANSACTION_DONE;
0220     return;
0221 }
0222 
0223 static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev)
0224 {
0225     struct oaktrail_hdmi_dev *hdmi_dev = dev;
0226     struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
0227     u32 stat;
0228 
0229     stat = HDMI_READ(HDMI_HISR);
0230 
0231     if (stat & HDMI_INTR_HPD) {
0232         HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD);
0233         HDMI_READ(HDMI_HISR);
0234     }
0235 
0236     if (stat & HDMI_INTR_I2C_FULL)
0237         hdmi_i2c_read(hdmi_dev);
0238 
0239     if (stat & HDMI_INTR_I2C_DONE)
0240         hdmi_i2c_transaction_done(hdmi_dev);
0241 
0242     complete(&i2c_dev->complete);
0243 
0244     return IRQ_HANDLED;
0245 }
0246 
0247 /*
0248  * choose alternate function 2 of GPIO pin 52, 53,
0249  * which is used by HDMI I2C logic
0250  */
0251 static void oaktrail_hdmi_i2c_gpio_fix(void)
0252 {
0253     void __iomem *base;
0254     unsigned int gpio_base = 0xff12c000;
0255     int gpio_len = 0x1000;
0256     u32 temp;
0257 
0258     base = ioremap((resource_size_t)gpio_base, gpio_len);
0259     if (base == NULL) {
0260         DRM_ERROR("gpio ioremap fail\n");
0261         return;
0262     }
0263 
0264     temp = readl(base + 0x44);
0265     DRM_DEBUG_DRIVER("old gpio val %x\n", temp);
0266     writel((temp | 0x00000a00), (base +  0x44));
0267     temp = readl(base + 0x44);
0268     DRM_DEBUG_DRIVER("new gpio val %x\n", temp);
0269 
0270     iounmap(base);
0271 }
0272 
0273 int oaktrail_hdmi_i2c_init(struct pci_dev *dev)
0274 {
0275     struct oaktrail_hdmi_dev *hdmi_dev;
0276     struct hdmi_i2c_dev *i2c_dev;
0277     int ret;
0278 
0279     hdmi_dev = pci_get_drvdata(dev);
0280 
0281     i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL);
0282     if (!i2c_dev)
0283         return -ENOMEM;
0284 
0285     i2c_dev->adap = &oaktrail_hdmi_i2c_adapter;
0286     i2c_dev->status = I2C_STAT_INIT;
0287     init_completion(&i2c_dev->complete);
0288     mutex_init(&i2c_dev->i2c_lock);
0289     i2c_set_adapdata(&oaktrail_hdmi_i2c_adapter, hdmi_dev);
0290     hdmi_dev->i2c_dev = i2c_dev;
0291 
0292     /* Enable HDMI I2C function on gpio */
0293     oaktrail_hdmi_i2c_gpio_fix();
0294 
0295     /* request irq */
0296     ret = request_irq(dev->irq, oaktrail_hdmi_i2c_handler, IRQF_SHARED,
0297               oaktrail_hdmi_i2c_adapter.name, hdmi_dev);
0298     if (ret) {
0299         DRM_ERROR("Failed to request IRQ for I2C controller\n");
0300         goto free_dev;
0301     }
0302 
0303     /* Adapter registration */
0304     ret = i2c_add_numbered_adapter(&oaktrail_hdmi_i2c_adapter);
0305     if (ret) {
0306         DRM_ERROR("Failed to add I2C adapter\n");
0307         goto free_irq;
0308     }
0309 
0310     return 0;
0311 
0312 free_irq:
0313     free_irq(dev->irq, hdmi_dev);
0314 free_dev:
0315     kfree(i2c_dev);
0316 
0317     return ret;
0318 }
0319 
0320 void oaktrail_hdmi_i2c_exit(struct pci_dev *dev)
0321 {
0322     struct oaktrail_hdmi_dev *hdmi_dev;
0323     struct hdmi_i2c_dev *i2c_dev;
0324 
0325     hdmi_dev = pci_get_drvdata(dev);
0326     i2c_del_adapter(&oaktrail_hdmi_i2c_adapter);
0327 
0328     i2c_dev = hdmi_dev->i2c_dev;
0329     kfree(i2c_dev);
0330     free_irq(dev->irq, hdmi_dev);
0331 }