⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 via_i2c.c

📁 via framebuffer driver
💻 C
字号:
/* * 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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -