Re: [PATCH 12/13] viafb: via_i2c.c, via_i2c.h, viamode.c, viamode.c - Kernel

This is a discussion on Re: [PATCH 12/13] viafb: via_i2c.c, via_i2c.h, viamode.c, viamode.c - Kernel ; On Mon, Jun 30, 2008 at 03:51:19PM +0800, JosephChan@via.com.tw wrote: > via_i2c.c, via_i2c.h: Implement i2c specification. > viamode.c, viamode.c: all support modes information. > > > Signed-off-by: Joseph Chan > > diff -Nur a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c > --- a/drivers/video/via/via_i2c.c 1970-01-01 08:00:00.000000000 ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: Re: [PATCH 12/13] viafb: via_i2c.c, via_i2c.h, viamode.c, viamode.c

  1. Re: [PATCH 12/13] viafb: via_i2c.c, via_i2c.h, viamode.c, viamode.c

    On Mon, Jun 30, 2008 at 03:51:19PM +0800, JosephChan@via.com.tw wrote:
    > via_i2c.c, via_i2c.h: Implement i2c specification.
    > viamode.c, viamode.c: all support modes information.
    >
    >
    > Signed-off-by: Joseph Chan
    >
    > diff -Nur a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
    > --- a/drivers/video/via/via_i2c.c 1970-01-01 08:00:00.000000000 +0800
    > +++ b/drivers/video/via/via_i2c.c 2008-06-30 08:53:33.000000000 +0800
    > @@ -0,0 +1,377 @@
    > +/*
    > + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
    > + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
    > +
    > + * This program is free software; you can redistribute it and/or
    > + * modify it under the terms of the GNU General Public
    > + * License as published by the Free Software Foundation;
    > + * either version 2, or (at your option) any later version.
    > +
    > + * This program is distributed in the hope that it will be useful,
    > + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
    > + * the implied warranty of MERCHANTABILITY or FITNESS FOR
    > + * A PARTICULAR PURPOSE.See the GNU General Public License
    > + * for more details.
    > +
    > + * You should have received a copy of the GNU General Public License
    > + * along with this program; if not, write to the Free Software
    > + * Foundation, Inc.,
    > + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    > + */
    > +
    > +#include "global.h"
    > +
    > +/* i2c delay for microsecond*/
    > +void viafb_delays(int count)
    > +{
    > + u8 data;
    > + while (count--) {
    > + /* delay 1 us */
    > + data = inb(DELAYPORT);
    > + data = inb(DELAYPORT);
    > + data = inb(DELAYPORT);
    > + data = inb(DELAYPORT);
    > + data = inb(DELAYPORT);
    > + }
    > +
    > +}
    > +
    > +/* Write I2C BUS SDA And SCL*/
    > +static void i2cWriteSdaScl(u8 sda, u8 scl)
    > +{
    > + u8 data;
    > + u16 port_addr;
    > +
    > + if (viaparinfo->chip_info->chip_on_slot == PORT_ON_AMR) {
    > +
    > + data = ((scl << 1) | sda) << 4;
    > + /* enable I2C port */
    > + data = data | BIT0;
    > +
    > + port_addr = I2CPORT;
    > + /* Write Register Value */
    > + viafb_write_reg(I2CPORTINDEX, port_addr, data);
    > + } else {
    > + if (viaparinfo->chip_info->chip_on_slot == PORT_ON_AGP) {
    > + data = ((scl << 1) | sda) << 4;
    > + /* enable GPIO write port */
    > + data = data | (BIT6 + BIT7);
    > + port_addr = GPIOPORT;
    > + /* Write Register Value */
    > + viafb_write_reg(GPIOPORTINDEX, port_addr, data);
    > + }
    > + }
    > +}
    > +
    > +static void i2cReadSdaScl(u8 *pSda, u8 *pScl)
    > +{
    > + u8 data;
    > + u16 port_addr;
    > +
    > + if (viaparinfo->chip_info->chip_on_slot == PORT_ON_AMR) {
    > + port_addr = I2CPORT;
    > + data = viafb_read_reg(port_addr, I2CPORTINDEX);
    > + *pSda = (data >> 2) & BIT0; /* get sda */
    > + *pScl = (data >> 3) & BIT0; /* get scl */
    > + } else {
    > + if (viaparinfo->chip_info->chip_on_slot == PORT_ON_AGP) {
    > + port_addr = GPIOPORT;
    > + data = viafb_read_reg(port_addr, GPIOPORTINDEX);
    > + *pSda = (data >> 2) & BIT0; /* get sda */
    > + *pScl = (data >> 3) & BIT0; /* get scl */
    > + }
    > + }
    > +}
    > +
    > +static void i2cWriteSdaSclDelay(u8 sda, u8 scl)
    > +{
    > + i2cWriteSdaScl(sda, scl);
    > + viafb_delays(16); /* Wait 16 uS */
    > +}
    > +
    > +static void i2cStartSignal(void)
    > +{
    > + i2cWriteSdaSclDelay(1, 1);
    > + i2cWriteSdaSclDelay(0, 1);
    > + i2cWriteSdaSclDelay(0, 0);
    > +}
    > +
    > +static void i2cStopSignal(void)
    > +{
    > + u8 data;
    > + u16 port_addr;
    > +
    > + i2cWriteSdaSclDelay(0, 0);
    > + i2cWriteSdaSclDelay(0, 1);
    > + i2cWriteSdaSclDelay(1, 1);
    > +
    > + if (viaparinfo->chip_info->chip_on_slot == PORT_ON_AGP) {
    > + /* disable GPIO write port */
    > + data = 0x3c;
    > + port_addr = GPIOPORT;
    > + /* Write Register Value */
    > + viafb_write_reg(GPIOPORTINDEX, port_addr, data);
    > + }
    > + viafb_delays(2);
    > +
    > +}
    > +
    > +static void disableSdaGPIO(void)
    > +{
    > + u8 data;
    > + u16 port_addr;
    > +
    > + if (viaparinfo->chip_info->chip_on_slot == PORT_ON_AGP) {
    > + port_addr = GPIOPORT;
    > + data = viafb_read_reg(port_addr, GPIOPORTINDEX);
    > + /* disable GPIO write port */
    > + data = data & (~BIT6);
    > + /* Write Register Value */
    > + viafb_write_reg(GPIOPORTINDEX, port_addr, data);
    > + }
    > +}
    > +
    > +static void writeSclGPIO(u8 scl)
    > +{
    > + u8 data;
    > + u16 port_addr;
    > +
    > + if (viaparinfo->chip_info->chip_on_slot == PORT_ON_AGP) {
    > + port_addr = GPIOPORT;
    > + data = viafb_read_reg(port_addr, GPIOPORTINDEX);
    > + data = data & (~BIT5);
    > + /* write data to clock */
    > + data = (data | (scl << 5)) & (~BIT6);
    > + /* Write Register Value */
    > + viafb_write_reg(GPIOPORTINDEX, port_addr, data);
    > + }
    > +}
    > +
    > +static int i2CWaitForSlave(void)
    > +{
    > + int time_out = 20000;
    > + u8 sda, scl;
    > +
    > + while (time_out--) {
    > + i2cReadSdaScl(&sda, &scl);
    > + if (scl)
    > + return OK; /* Successful stall */
    > + viafb_delays(1); /* wait 1 uS */
    > + }
    > + return FAIL; /* Slave fail */
    > +}
    > +
    > +static int i2cOutByte(u8 data)
    > +{
    > + u8 sda, scl;
    > + u8 out_byte;
    > + int bit_count = 8;
    > + int status;
    > +
    > + out_byte = data;
    > + while (bit_count--) {
    > + sda = (out_byte >> 7) & 1; /* Load MSB */
    > + out_byte = out_byte << 1; /* next bit. */
    > + i2cWriteSdaSclDelay(sda, 0);
    > + i2cWriteSdaSclDelay(sda, 1);
    > +
    > + status = i2CWaitForSlave();
    > + if (status == FAIL)
    > + return status;
    > + i2cWriteSdaSclDelay(sda, 0);
    > +
    > + }
    > +
    > + if ((viaparinfo->chip_info->chip_on_slot == PORT_ON_AGP)) {
    > +
    > + writeSclGPIO(0);
    > + disableSdaGPIO();
    > + viafb_delays(2);
    > + writeSclGPIO(1);
    > + viafb_delays(2);
    > + i2cReadSdaScl(&sda, &scl);
    > + writeSclGPIO(0);
    > + viafb_delays(2);
    > + if (sda == 0)
    > + status = OK;
    > + else
    > + status = FAIL;
    > + } else {
    > + i2cWriteSdaSclDelay(1, 0);
    > + i2cWriteSdaSclDelay(1, 1);
    > + status = i2CWaitForSlave();
    > + if (status == FAIL)
    > + return status;
    > +
    > + i2cReadSdaScl(&sda, &scl);
    > + if (sda == 0) {
    > + i2cWriteSdaSclDelay(1, 0);
    > + status = OK;
    > + } else {
    > +
    > + i2cWriteSdaSclDelay(1, 0);
    > + status = FAIL;
    > + }
    > + }
    > + return status;
    > +}
    > +
    > +static int i2cInputByte(u8 *pInByte, int ack)
    > +{
    > +
    > + int bit_count = 8;
    > + u8 sda, scl;
    > + u8 data = 0;
    > + int status;
    > +
    > + disableSdaGPIO();
    > +
    > + while (bit_count--) {
    > + if ((viaparinfo->chip_info->chip_on_slot == PORT_ON_AGP)) {
    > +
    > + writeSclGPIO(1);
    > + viafb_delays(2);
    > + status = i2CWaitForSlave();
    > + if (status == FAIL)
    > + return FAIL;
    > + i2cReadSdaScl(&sda, &scl);
    > + data = data << 1;
    > + data |= sda;
    > + writeSclGPIO(0);
    > + viafb_delays(2);
    > +
    > + } else {
    > + i2cWriteSdaSclDelay(1, 1);
    > + status = i2CWaitForSlave();
    > + if (status == FAIL)
    > + return FAIL;
    > + i2cReadSdaScl(&sda, &scl);
    > + data = data << 1;
    > + data |= sda;
    > + i2cWriteSdaSclDelay(1, 0);
    > + }
    > + }
    > + *pInByte = data;
    > +
    > + if (ack) {
    > + i2cWriteSdaSclDelay(0, 0);
    > + i2cWriteSdaSclDelay(0, 1);
    > + status = i2CWaitForSlave();
    > + if (status == FAIL)
    > + return status;
    > + i2cWriteSdaSclDelay(0, 0);
    > + } else {
    > + i2cWriteSdaSclDelay(1, 0);
    > + i2cWriteSdaSclDelay(1, 1);
    > + status = i2CWaitForSlave();
    > + if (status == FAIL)
    > + return status;
    > + }
    > + i2cWriteSdaSclDelay(1, 0);
    > +
    > + return OK;
    > +}
    > +
    > +int viafb_i2cReadByte(u8 slave_addr, u8 index, u8 *pData)
    > +{
    > +
    > + int status;
    > +
    > + i2cStartSignal();
    > +
    > + status = i2cOutByte(slave_addr);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > + status = i2cOutByte(index);
    > +
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > +
    > + i2cStartSignal();
    > + status = i2cOutByte(slave_addr | BIT0);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > + status = i2cInputByte(pData, 0);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > +
    > + i2cStopSignal();
    > + return OK;
    > +}
    > +
    > +int viafb_i2cWriteByte(u8 slave_addr, u8 index, u8 data)
    > +{
    > +
    > + int status;
    > +
    > + i2cStartSignal();
    > + status = i2cOutByte(slave_addr);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > + status = i2cOutByte(index);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > + status = i2cOutByte(data);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > + i2cStopSignal();
    > + return OK;
    > +}
    > +
    > +int viafb_i2cReadBytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
    > +{
    > +
    > + int status, i;
    > +
    > + i2cStartSignal();
    > +
    > + status = i2cOutByte(slave_addr);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > +
    > + status = i2cOutByte(index);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > +
    > + i2cStartSignal();
    > + status = i2cOutByte(slave_addr | BIT0);
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return FAIL;
    > + }
    > +
    > + for (i = 0; i < buff_len; i++) {
    > + if (buff_len == 1)
    > + status = i2cInputByte(buff, 0); /* send NACK */
    > + else if (i < buff_len - 1)
    > + status = i2cInputByte(buff, 1); /* send ACK */
    > + else
    > + status = i2cInputByte(buff, 0); /* send NACK */
    > + if (status == FAIL) {
    > + i2cStopSignal();
    > + return (FAIL);
    > + }
    > + buff++;
    > + }
    > +
    > + i2cStopSignal();
    > + return OK;
    > +}


    This looks like an attempt at re-doing the already extant i2c gpio
    algorithm. Either export via gpiolib and use the i2c-gpio adapter or
    use the i2c bit-banging algorithm.

    --
    Ben
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [PATCH 12/13] viafb: via_i2c.c, via_i2c.h, viamode.c, viamode.c

    > This looks like an attempt at re-doing the already extant i2c gpio
    > algorithm. Either export via gpiolib and use the i2c-gpio adapter or
    > use the i2c bit-banging algorithm.


    Agreed - but this can be done a lot more easily after a merge.


    Alan
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread