summaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-aspeed/i2c-slave-eeprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-aspeed/i2c-slave-eeprom.c')
-rw-r--r--arch/arm/plat-aspeed/i2c-slave-eeprom.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/arch/arm/plat-aspeed/i2c-slave-eeprom.c b/arch/arm/plat-aspeed/i2c-slave-eeprom.c
new file mode 100644
index 0000000..fd53f1a
--- /dev/null
+++ b/arch/arm/plat-aspeed/i2c-slave-eeprom.c
@@ -0,0 +1,141 @@
+/********************************************************************************
+* File Name : linux/arch/arm/plat-aspeed/i2c-slave-eeprom.c
+* Author : Ryan chen
+* Description : ASPEED I2C Device
+*
+* Copyright (C) ASPEED Technology Inc.
+* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+* History :
+* 1. 2013/05/30 ryan chen create this file
+*
+********************************************************************************/
+#include <linux/i2c.h>
+#if defined(CONFIG_COLDFIRE)
+#include <asm/arch/ast_i2c.h>
+#else
+#include <plat/ast_i2c.h>
+#endif
+
+#ifdef I2C_EEPROM
+#define EEPROM_DBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
+#else
+#define EEPROM_DBUG(fmt, args...)
+#endif
+
+static u8 cmd_buf[1] = {0};
+static struct i2c_msg cmd_msg = {
+ .addr = 0x04,
+ .len = 1,
+ .buf = cmd_buf,
+};
+
+//Note 10 byte data memory share for all bus slave device ...........
+#define BUF_SIZE 10
+
+static u8 store_memory[BUF_SIZE] = {0x03,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
+ // RO, RW, .................
+static struct i2c_msg data_msg = {
+ .addr = 0x04,
+ .len = BUF_SIZE,
+ .buf = store_memory,
+};
+static u8 mem_index = 0;
+static u8 slave_stage = INIT_STAGE;
+
+extern void i2c_slave_init(struct i2c_msg **msgs)
+{
+ *msgs = &cmd_msg;
+}
+
+extern void i2c_slave_xfer(i2c_slave_event_t event, struct i2c_msg **msgs)
+{
+ EEPROM_DBUG("[event %d] \n",event);
+ switch(event) {
+ case I2C_SLAVE_EVENT_START_READ:
+ cmd_msg.flags = I2C_M_RD;
+ data_msg.flags = I2C_M_RD;
+ if(slave_stage == INIT_STAGE) {
+ EEPROM_DBUG("Rt DATA_MSG [%x]\n",data_msg.buf[0]);
+ slave_stage = DATA_STAGE;
+ *msgs = &data_msg;
+ } else {
+ //CMD_STAGE
+ if(cmd_msg.buf[0] != ((cmd_msg.addr << 1)|1))
+ printk("START READ ADDR Error %x\n",cmd_msg.buf[0]);
+
+ EEPROM_DBUG("Rt CMD_DATA_MSG data [%x]\n",store_memory[mem_index]);
+ cmd_msg.buf[0] = store_memory[mem_index];
+ mem_index++;
+ mem_index %=BUF_SIZE;
+ slave_stage = CMD_DATA_STAGE;
+ *msgs = &cmd_msg;
+ }
+ break;
+ case I2C_SLAVE_EVENT_START_WRITE:
+ EEPROM_DBUG("Rt CMD_MSG START_WRITE %x\n",cmd_msg.buf[0]);
+ cmd_msg.flags = 0;
+ if(cmd_msg.buf[0] != cmd_msg.addr <<1)
+ printk("ERROR ADDRESS Match [%x] \n", cmd_msg.buf[0]);
+ slave_stage = CMD_STAGE;
+
+ *msgs = &cmd_msg;
+
+ break;
+
+ case I2C_SLAVE_EVENT_WRITE:
+ cmd_msg.flags = 0;
+ if(slave_stage == CMD_STAGE) {
+ EEPROM_DBUG("w CMD = [index %x] \n",cmd_msg.buf[0]);
+ mem_index = cmd_msg.buf[0];
+ mem_index %= BUF_SIZE;
+ slave_stage = CMD_DATA_STAGE;
+ *msgs = &cmd_msg;
+ } else {
+ EEPROM_DBUG("w index %d CMD_DATA [%x] \n",mem_index, cmd_msg.buf[0]);
+ if(mem_index !=0)
+ store_memory[mem_index] = cmd_msg.buf[0];
+ mem_index++;
+ mem_index %=BUF_SIZE;
+ EEPROM_DBUG("Rt CMD_DATA_MSG \n");
+ *msgs = &cmd_msg;
+ }
+ break;
+ case I2C_SLAVE_EVENT_READ:
+ cmd_msg.flags = I2C_M_RD;
+ if(slave_stage == CMD_DATA_STAGE) {
+ cmd_msg.buf[0] = store_memory[mem_index];
+ mem_index++;
+ mem_index %=BUF_SIZE;
+ EEPROM_DBUG("Rt CMD_DATA_MSG [%x]\n",cmd_msg.buf[0]);
+ *msgs = &cmd_msg;
+ } else {
+ EEPROM_DBUG("Rt DATA_MSG [%x]\n",data_msg.buf[0]);
+ *msgs = &data_msg;
+ }
+ break;
+ case I2C_SLAVE_EVENT_NACK:
+ cmd_msg.flags = I2C_M_RD;
+ slave_stage = INIT_STAGE;
+ *msgs = &cmd_msg;
+
+ break;
+
+ case I2C_SLAVE_EVENT_STOP:
+ cmd_msg.flags = I2C_M_RD;
+ slave_stage = INIT_STAGE;
+ *msgs = &cmd_msg;
+ break;
+ }
+
+}
OpenPOWER on IntegriCloud