Messages in this thread | | | Date | Fri, 11 Jul 2003 13:24:19 +0200 | From | Kurt Garloff <> | Subject | i2c-pyxis |
| |
Hi,
here's my try to get i2c supported on my PYXIS (21174) chipset.
It seems to work, but I can't see the memory which should be visible on the i2c bus, so it probably does not.
I lack time to work on it, so maybe somebody wants to start from what I have.
Regards, -- Kurt Garloff <kurt@garloff.de> [Koeln, DE] Physics:Plasma modeling <garloff@plasimo.phys.tue.nl> [TU Eindhoven, NL] Linux:SCSI, Security <garloff@suse.de> [SuSE Nuernberg, DE] /* i2c-pyxis.c Copyright (c) 2003 Kurt Garloff <garloff@suse.de>
Based on i2c-tsunami.c from Oleg Vdovikin <vdovikin@jscc.ru> Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and Simon Vogl
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 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This interfaces to the I2C bus of the PYXIS 21174 chipsets to gain access to the on-board I2C devices.
For more information refer to Compaq's Miata specification. */
#include <linux/version.h> #include <linux/module.h> #include <asm/io.h> #include <asm/hwrpb.h> #include <asm/core_cia.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #define LM_DATE "20020915" #define LM_VERSION "2.6.5" #include <linux/init.h> //#include <linux/delay.h>
#ifdef MODULE_LICENSE MODULE_LICENSE("GPL"); #endif
/* IIC register of PYXIS (PYXIS_IIC_CTRL): 20.2 PYXIS IIC_CTRL REGISTER - 87.A000.02C0
bit name description
0 read_data current state of read data pin 1 read_clk current state of clock pin 2 data_en enable data out 3 data data to be driven 4 clk_en enable clock out 5 clk clock to be driven */
#define PYX_DR 0x01 /* Data receive - RO */ #define PYX_CKR 0x02 /* Clock receive - RO */ #define PYX_DSE 0x04 /* Enable data output - WO */ #define PYX_DS 0x08 /* Data send - Must be a 1 to receive - WO */ #define PYX_CKE 0x10 /* Enable clock output - WO */ #define PYX_CKS 0x20 /* Clock send - WO */
#ifdef MODULE static #else extern #endif int __init i2c_pyxis_init(void); static int __init i2c_pyxis_cleanup(void); static void i2c_pyxis_inc(struct i2c_adapter *adapter); static void i2c_pyxis_dec(struct i2c_adapter *adapter);
#ifdef MODULE extern int init_module(void); extern int cleanup_module(void); #endif /* MODULE */
#define vuip volatile unsigned int * extern inline void writempd(unsigned long value) { *(vuip)PYXIS_IIC_CTRL = value; mb(); }
extern inline unsigned long readmpd(void) { return *(vuip)PYXIS_IIC_CTRL; }
static inline unsigned long pyxis_rcv_to_snd(unsigned long regs) { return (regs & ~0x2bULL) | (regs & PYX_DR ? PYX_DS : 0) | (regs & PYX_CKR? PYX_CKS: 0); }
static void bit_pyxis_setscl(void *data, int val) { /* read currently setted bits to modify them */ unsigned long bits = readmpd(); bits = pyxis_rcv_to_snd(bits); /* assume output == input */ bits |= PYX_CKE;
if (val) bits |= PYX_CKS; else bits &= ~PYX_CKS;
writempd(bits); //bits &= ~PYX_CKE; //writempd(bits); //readmpd(); }
static void bit_pyxis_setsda(void *data, int val) { /* read currently setted bits to modify them */ unsigned long bits = readmpd(); bits = pyxis_rcv_to_snd(bits); /* assume output == input */ bits |= PYX_DSE; if (val) bits |= PYX_DS; else bits &= ~PYX_DS;
writempd(bits); //bits &= ~PYX_DSE; //writempd(bits); //readmpd(); }
static int bit_pyxis_getscl(void *data) { //unsigned long bits = readmpd(); //bits = pyxis_rcv_to_snd(bits); /* assume output == input */ //writempd (bits & ~PYX_CKE); return (0 != (readmpd() & PYX_CKR)); }
static int bit_pyxis_getsda(void *data) { //unsigned long bits = readmpd(); //bits = pyxis_rcv_to_snd(bits); /* assume output == input */ //writempd (bits & ~PYX_DSE); return (0 != (readmpd() & PYX_DR)); }
static struct i2c_algo_bit_data pyxis_i2c_bit_data = { NULL, bit_pyxis_setsda, bit_pyxis_setscl, bit_pyxis_getsda, bit_pyxis_getscl, 10, 10, 50 /* delays/timeout */ };
static struct i2c_adapter pyxis_i2c_adapter = { "I2C PYXIS adapter", I2C_HW_B_PYXIS, NULL, &pyxis_i2c_bit_data, i2c_pyxis_inc, i2c_pyxis_dec, NULL, NULL, };
void i2c_pyxis_inc(struct i2c_adapter *adapter) { MOD_INC_USE_COUNT; }
void i2c_pyxis_dec(struct i2c_adapter *adapter) { MOD_DEC_USE_COUNT; }
int __init i2c_pyxis_init(void) { int res; printk("i2c-pyxis.o version %s (%s)\n", LM_VERSION, LM_DATE);
if (hwrpb->sys_type != ST_DEC_MIATA) { printk("i2c-pyxis.o: not PYXIS based system (%ld), module not inserted.\n", hwrpb->sys_type); return -ENXIO; } else { printk("i2c-pyxis.o: using PYXIS IIC CTRL at 0x%lx: %02lx.\n", PYXIS_IIC_CTRL, readmpd()); } if ((res = i2c_bit_add_bus(&pyxis_i2c_adapter))) { printk("i2c-pyxis.o: I2C adapter registration failed\n"); } else { printk("i2c-pyxis.o: I2C bus initialized\n"); }
return res; }
int __init i2c_pyxis_cleanup(void) { int res;
if ((res = i2c_bit_del_bus(&pyxis_i2c_adapter))) { printk("i2c-pyxis.o: i2c_bit_del_bus failed, module not removed\n"); return res; }
return 0; }
EXPORT_NO_SYMBOLS;
#ifdef MODULE
MODULE_AUTHOR("Kurt Garloff <garloff@suse.de>"); MODULE_DESCRIPTION("PYXIS I2C/SMBus driver");
int init_module(void) { return i2c_pyxis_init(); }
int cleanup_module(void) { return i2c_pyxis_cleanup(); }
#endif /* MODULE */ [unhandled content-type:application/pgp-signature] | |