* 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);
#define MAVEN_WRITE (0x1B<<1)
#define MAVEN_READ ((0x1B<<1)|1)
#define I2C_CLOCK 0x20
#define I2C_DATA 0x10
#define I2C_CLOCK 0x20
#define I2C_DATA 0x10
#define DDC1_CLK 0x08
#define DDC1_DATA 0x02
#define DDC1B_CLK 0x10
#define DDC1B_DATA 0x04
#define DDC2_CLK 0x04
#define DDC2_DATA 0x01
status_t i2c_sec_tv_adapter()
{
status_t result = B_ERROR;
if (!si->ps.secondary_head) return result;
* (they will be pulled 'passive-high' when disabled) */
* check for 'shortcut', indicating the Matrox VGA->TV adapter is connected */
snooze(2);
snooze(2);
snooze(5);
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;
program =
(clock ? 0 : I2C_CLOCK)|
(data ? 0 : I2C_DATA);
required =
(clock ? I2C_CLOCK : 0);
delay(I2C_DELAY);
{
delay(I2C_DELAY);
count++;
if (count>I2C_TIMEOUT)
{
return -1;
}
}
return 0;
}
int i2c_get_data()
{
int data = 0;
int clock;
int count=0;
do
{
clock = (data&I2C_CLOCK) ? 1 : 0;
data = (data&I2C_DATA) ? 1 : 0;
count++;
if (count>I2C_TIMEOUT)
{
return -1;
}
delay(I2C_DELAY);
}while (!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;
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);
}
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)
{
return B_OK;
}
status_t i2c_maven_probe(void)
{
int ack;
i2c_start();
{
ack = i2c_sendbyte(MAVEN_READ);
}
i2c_stop();
if (ack==0)
{
return B_OK;
}
else
{
return B_ERROR;
}
}