added via accelerant, a copy of skeleton driver yet.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13604 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* i2c interface for the G400 MAVEN under BeOS
|
||||
*
|
||||
* Provides I2CR,I2CW - functions to parallel DACW,DACR
|
||||
* Bus should be run at max. 100kHz: see original Philips I2C specification
|
||||
*
|
||||
* Much help was provided by observing the Linux i2c code,
|
||||
* so thanks go to: Gerd Knorr
|
||||
*
|
||||
* Other authors:
|
||||
* Mark Watson 6/2000,
|
||||
* Rudolf Cornelissen 12/2002-12/2003
|
||||
*/
|
||||
|
||||
#define MODULE_BIT 0x00004000
|
||||
|
||||
#include "std.h"
|
||||
|
||||
int i2c_set_lines(int clock, int data);
|
||||
int i2c_get_data(void);
|
||||
void i2c_start(void);
|
||||
void i2c_stop(void);
|
||||
void i2c_high(void);
|
||||
void i2c_low(void);
|
||||
int i2c_get_ack(void);
|
||||
void i2c_send_ack(void);
|
||||
int i2c_sendbyte(unsigned char data);
|
||||
unsigned char i2c_readbyte(int ack_required);
|
||||
|
||||
/*which device on the bus is the MAVEN?*/
|
||||
#define MAVEN_WRITE (0x1B<<1)
|
||||
#define MAVEN_READ ((0x1B<<1)|1)
|
||||
|
||||
#define I2C_CLOCK 0x20
|
||||
#define I2C_DATA 0x10
|
||||
|
||||
/* NV-TVO I2C for G200, G400 */
|
||||
#define I2C_CLOCK 0x20
|
||||
#define I2C_DATA 0x10
|
||||
/* primary head DDC for Mystique(?), G100, G200, G400 */
|
||||
#define DDC1_CLK 0x08
|
||||
#define DDC1_DATA 0x02
|
||||
/* primary head DDC for Millennium, Millennium II */
|
||||
#define DDC1B_CLK 0x10
|
||||
#define DDC1B_DATA 0x04
|
||||
/* secondary head DDC for G400, G450 and G550 */
|
||||
#define DDC2_CLK 0x04
|
||||
#define DDC2_DATA 0x01
|
||||
|
||||
status_t i2c_sec_tv_adapter()
|
||||
{
|
||||
status_t result = B_ERROR;
|
||||
|
||||
/* The secondary DDC channel only exist on dualhead cards */
|
||||
if (!si->ps.secondary_head) return result;
|
||||
|
||||
/* make sure the output lines will be active-low when enabled
|
||||
* (they will be pulled 'passive-high' when disabled) */
|
||||
// DXIW(GENIODATA,0x00);
|
||||
/* send out B_STOP condition on secondary head DDC channel and use it to
|
||||
* check for 'shortcut', indicating the Matrox VGA->TV adapter is connected */
|
||||
|
||||
/* make sure SDA is low */
|
||||
// DXIW(GENIOCTRL, (DXIR(GENIOCTRL) | DDC2_DATA));
|
||||
snooze(2);
|
||||
/* make sure SCL should be high */
|
||||
// DXIW(GENIOCTRL, (DXIR(GENIOCTRL) & ~DDC2_CLK));
|
||||
snooze(2);
|
||||
/* if SCL is low then the bus is blocked by a TV adapter */
|
||||
// if (!(DXIR(GENIODATA) & DDC2_CLK)) result = B_OK;
|
||||
snooze(5);
|
||||
/* set SDA while SCL should be set (generates actual bus-stop condition) */
|
||||
// DXIW(GENIOCTRL, (DXIR(GENIOCTRL) & ~DDC2_DATA));
|
||||
snooze(5);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-----------------------------
|
||||
*low level hardware access
|
||||
*/
|
||||
#define I2C_DELAY 2
|
||||
#define I2C_TIMEOUT 100
|
||||
int i2c_set_lines(int clock,int data)
|
||||
{
|
||||
int count=0;
|
||||
int program;
|
||||
int required;
|
||||
|
||||
/*work out which bits to zero*/
|
||||
program =
|
||||
(clock ? 0 : I2C_CLOCK)|
|
||||
(data ? 0 : I2C_DATA);
|
||||
|
||||
/*what value do I require on data lines*/
|
||||
required =
|
||||
(clock ? I2C_CLOCK : 0);
|
||||
|
||||
/*set the bits to zero*/
|
||||
// DXIW(GENIOCTRL,program); /*drive these bits*/
|
||||
// DXIW(GENIODATA,0x00); /*to zero*/
|
||||
|
||||
/*wait a bit*/
|
||||
delay(I2C_DELAY);
|
||||
|
||||
/*loop until the clock is as required*/
|
||||
// while ((DXIR(GENIODATA)&I2C_CLOCK)!=required)
|
||||
{
|
||||
delay(I2C_DELAY);
|
||||
count++;
|
||||
if (count>I2C_TIMEOUT)
|
||||
{
|
||||
// LOG(8,("I2C: Timeout on set lines - clock:%d data:%d actual:%x\n",clock,data,DXIR(GENIODATA)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_get_data()
|
||||
{
|
||||
int data = 0;
|
||||
int clock;
|
||||
int count=0;
|
||||
|
||||
do
|
||||
{
|
||||
/*read the data and clock lines*/
|
||||
// data = DXIR(GENIODATA);
|
||||
clock = (data&I2C_CLOCK) ? 1 : 0;
|
||||
data = (data&I2C_DATA) ? 1 : 0;
|
||||
|
||||
/*manage timeout*/
|
||||
count++;
|
||||
if (count>I2C_TIMEOUT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*wait a bit, so not hammering bus*/
|
||||
delay(I2C_DELAY);
|
||||
|
||||
}while (!clock); /*wait for high clock*/
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------
|
||||
*Standard I2C operations
|
||||
*/
|
||||
void i2c_start()
|
||||
{
|
||||
int error=0;
|
||||
|
||||
error+= i2c_set_lines(0,1);
|
||||
error+= i2c_set_lines(1,1);
|
||||
error+= i2c_set_lines(1,0);
|
||||
error+= i2c_set_lines(0,0);
|
||||
|
||||
if (error)
|
||||
{
|
||||
LOG(8,("I2C: start - %d\n",error));
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_stop()
|
||||
{
|
||||
int error=0;
|
||||
|
||||
error+= i2c_set_lines(0,0);
|
||||
error+= i2c_set_lines(1,0);
|
||||
error+= i2c_set_lines(1,1);
|
||||
error+= i2c_set_lines(0,1);
|
||||
|
||||
if (error)
|
||||
{
|
||||
LOG(8,("I2C: stop - %d\n",error));
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_high()
|
||||
{
|
||||
int error=0;
|
||||
|
||||
error+= i2c_set_lines(0,1);
|
||||
error+= i2c_set_lines(1,1);
|
||||
error+= i2c_set_lines(0,1);
|
||||
|
||||
if (error)
|
||||
{
|
||||
LOG(8,("I2C: high - %d\n",error));
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_low()
|
||||
{
|
||||
int error=0;
|
||||
|
||||
error+= i2c_set_lines(0,0);
|
||||
error+= i2c_set_lines(1,0);
|
||||
error+= i2c_set_lines(0,0);
|
||||
|
||||
if (error)
|
||||
{
|
||||
LOG(8,("I2C: low - %d\n",error));
|
||||
}
|
||||
}
|
||||
|
||||
int i2c_get_ack()
|
||||
{
|
||||
int error=0;
|
||||
int ack;
|
||||
|
||||
error+= i2c_set_lines(0,1);
|
||||
error+= i2c_set_lines(1,1);
|
||||
ack = i2c_get_data();
|
||||
error+= i2c_set_lines(0,1);
|
||||
|
||||
if (error)
|
||||
{
|
||||
LOG(8,("I2C: get_ack - %d value:%x\n",error,ack));
|
||||
}
|
||||
|
||||
return ack;
|
||||
}
|
||||
|
||||
void i2c_send_ack()
|
||||
{
|
||||
int error=0;
|
||||
|
||||
error+= i2c_set_lines(0,0);
|
||||
error+= i2c_set_lines(1,0);
|
||||
error+= i2c_set_lines(0,0);
|
||||
|
||||
if (error)
|
||||
{
|
||||
LOG(8,("I2C: send_ack - %d\n",error));
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------
|
||||
*use above functions to send and receive bytes
|
||||
*/
|
||||
|
||||
int i2c_sendbyte(unsigned char data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=7; i>=0; i--)
|
||||
{
|
||||
if (data&(1<<i))
|
||||
{
|
||||
i2c_high();
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_low();
|
||||
}
|
||||
}
|
||||
|
||||
return i2c_get_ack();
|
||||
}
|
||||
|
||||
unsigned char i2c_readbyte(int ack_required)
|
||||
{
|
||||
int i;
|
||||
unsigned char data=0;
|
||||
|
||||
/*read data*/
|
||||
i2c_set_lines(0,1);
|
||||
for (i=7; i>=0; i--)
|
||||
{
|
||||
i2c_set_lines(1,1);
|
||||
if (i2c_get_data()==1)
|
||||
data |= (1<<i);
|
||||
i2c_set_lines(0,1);
|
||||
}
|
||||
|
||||
/*send acknowledge*/
|
||||
if (ack_required) i2c_send_ack();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*-------------------------------------------
|
||||
*PUBLIC functions
|
||||
*/
|
||||
int i2c_maven_read(unsigned char address)
|
||||
{
|
||||
int error=0;
|
||||
int data;
|
||||
|
||||
i2c_start();
|
||||
{
|
||||
error+=i2c_sendbyte(MAVEN_READ);
|
||||
error+=i2c_sendbyte(address);
|
||||
data = i2c_readbyte(0);
|
||||
}
|
||||
i2c_stop();
|
||||
if (error>0) LOG(8,("I2C: MAVR ERROR - %x\n",error));
|
||||
return data;
|
||||
}
|
||||
|
||||
void i2c_maven_write(unsigned char address, unsigned char data)
|
||||
{
|
||||
int error=0;
|
||||
|
||||
i2c_start();
|
||||
{
|
||||
error+=i2c_sendbyte(MAVEN_WRITE);
|
||||
error+=i2c_sendbyte(address);
|
||||
error+=i2c_sendbyte(data);
|
||||
}
|
||||
i2c_stop();
|
||||
if (error>0) LOG(8,("I2C: MAVW ERROR - %x\n",error));
|
||||
}
|
||||
|
||||
status_t i2c_init(void)
|
||||
{
|
||||
/*init g400 i2c*/
|
||||
// DXIW(GENIODATA,0x00); /*to zero*/
|
||||
// DXIW(GENIOCTRL,0x30); /*drive clock and data*/
|
||||
// DXIW(GENIOCTRL,0x00); /*stop driving*/
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t i2c_maven_probe(void)
|
||||
{
|
||||
int ack;
|
||||
|
||||
/*scan the bus for the MAVEN*/
|
||||
i2c_start();
|
||||
{
|
||||
ack = i2c_sendbyte(MAVEN_READ);
|
||||
}
|
||||
i2c_stop();
|
||||
if (ack==0)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user