1 From e1618e943f60a4f8f778c4f7c389e2fa13eb0a83 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Thu, 26 Jun 2008 16:29:56 -0600
4 Subject: [PATCH] Add I2C support for the M5445x platforms.
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
9 drivers/i2c/busses/Kconfig | 10 +
10 drivers/i2c/busses/Makefile | 1 +
11 drivers/i2c/busses/i2c-mcf.c | 573 ++++++++++++++++++++++++++++++++++++++++++
12 drivers/i2c/busses/i2c-mcf.h | 75 ++++++
13 4 files changed, 659 insertions(+), 0 deletions(-)
14 create mode 100644 drivers/i2c/busses/i2c-mcf.c
15 create mode 100644 drivers/i2c/busses/i2c-mcf.h
17 --- a/drivers/i2c/busses/Kconfig
18 +++ b/drivers/i2c/busses/Kconfig
19 @@ -302,6 +302,16 @@ config I2C_POWERMAC
20 This support is also available as a module. If so, the module
21 will be called i2c-powermac.
24 + tristate "MCF ColdFire"
25 + depends on I2C && EXPERIMENTAL
27 + If you say yes to this option, support will be included for the
28 + I2C on most ColdFire CPUs
30 + This driver can also be built as a module. If so, the module
31 + will be called i2c-mcf.
34 tristate "MPC107/824x/85xx/52xx/86xx"
36 --- a/drivers/i2c/busses/Makefile
37 +++ b/drivers/i2c/busses/Makefile
38 @@ -53,6 +53,7 @@ obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3
39 obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
40 obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
41 obj-$(CONFIG_I2C_MCF548x) += i2c-mcf548x.o
42 +obj-$(CONFIG_I2C_MCF) += i2c-mcf.o
44 ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
45 EXTRA_CFLAGS += -DDEBUG
47 +++ b/drivers/i2c/busses/i2c-mcf.c
50 + i2c-mcf.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
52 + Copyright (c) 2005, Derek CL Cheung <derek.cheung@sympatico.ca>
53 + <http://www3.sympatico.ca/derek.cheung>
55 + Copyright (c) 2006-2007, emlix
56 + Sebastian Hess <sh@emlix.com>
58 + Copyright (c) 2006-2007 Freescale Semiconductor, Inc
59 + Yaroslav Vinogradov <yaroslav.vinogradov@freescale.com>
60 + Matt Waddel <Matt.Waddel@freescale.com>
62 + This program is free software; you can redistribute it and/or modify
63 + it under the terms of the GNU General Public License as published by
64 + the Free Software Foundation; either version 2 of the License, or
65 + (at your option) any later version.
67 + This program is distributed in the hope that it will be useful,
68 + but WITHOUT ANY WARRANTY; without even the implied warranty of
69 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70 + GNU General Public License for more details.
72 + You should have received a copy of the GNU General Public License
73 + along with this program; if not, write to the Free Software
74 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
78 + Initial Release - developed on uClinux with 2.6.9 kernel
81 + Modified to be more generic and added support for
84 + This I2C adaptor supports the ColdFire CPU I2C module. Since most Coldfire
85 + CPUs' I2C module use the same register set (e.g., MCF5249), the code is very
86 + portable and re-usable to other Coldfire CPUs.
88 + The transmission frequency is set at about 100KHz for the CPU board with
89 + 8MHz crystal. If the CPU board uses different system clock frequency, you
90 + should change the following line:
91 + static int __init i2c_coldfire_init(void)
94 + // Set transmission frequency 0x15 = ~100kHz
95 + *MCF_I2C_I2FDR = 0x15;
99 + Remember to perform a dummy read to set the ColdFire CPU's I2C module for
100 + read before reading the actual byte from a device
102 + The I2C_SM_BUS_BLOCK_DATA function are not yet ready but most lm_senors
106 +#include <linux/init.h>
107 +#include <linux/module.h>
108 +#include <linux/kernel.h>
109 +#include <linux/errno.h>
110 +#include <linux/i2c.h>
111 +#include <linux/delay.h>
112 +#include <linux/string.h>
113 +#include <asm/coldfire.h>
114 +#include <asm/mcfsim.h>
115 +#include <asm/types.h>
116 +#include <linux/platform_device.h>
117 +#include "i2c-mcf.h"
120 +static struct i2c_algorithm coldfire_algorithm = {
121 + /*.name = "ColdFire I2C algorithm",
122 + .id = I2C_ALGO_SMBUS,*/
123 + .smbus_xfer = coldfire_i2c_access,
124 + .master_xfer = coldfire_i2c_master,
125 + .functionality = coldfire_func,
129 +static struct i2c_adapter coldfire_adapter = {
130 + .owner = THIS_MODULE,
131 + .class = I2C_CLASS_HWMON,
132 + .algo = &coldfire_algorithm,
133 + .name = "ColdFire I2C adapter",
140 +static inline int coldfire_do_first_start(__u16 addr,__u16 flags)
144 + * Generate a stop and put the I2C module into slave mode
146 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MSTA;
149 + * Generate a new Start signal
151 + err = coldfire_i2c_start(flags & I2C_M_RD ? I2C_SMBUS_READ : I2C_SMBUS_WRITE,
152 + addr, FIRST_START);
153 + if(err) return err;
156 + lastop = flags & I2C_M_RD; /* Ensure everything for new start */
162 + * read one byte data from the I2C bus
164 +static int coldfire_read_data(u8 * const rxData, const enum I2C_ACK_TYPE ackType) {
168 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MTX; /* master receive mode*/
170 + if (ackType == NACK)
171 + *MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK; /* generate NA */
173 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_TXAK; /* generate ACK */
176 + /* read data from the I2C bus */
177 + *rxData = *MCF_I2C_I2DR;
179 + /* printk(">>> %s I2DR data is %.2x \n", __FUNCTION__, *rxData); */
181 + /* wait for data transfer to complete */
183 + while (timeout-- && !(*MCF_I2C_I2SR & MCF_I2C_I2SR_IIF))
186 + printk("%s - I2C IIF never set. Timeout is %d \n", __FUNCTION__,
190 + /* reset the interrupt bit */
191 + *MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;
202 + * write one byte data onto the I2C bus
204 +static int coldfire_write_data(const u8 txData) {
210 + *MCF_I2C_I2CR |= MCF_I2C_I2CR_MTX; /* I2C module into TX mode */
211 + *MCF_I2C_I2DR = txData; /* send the data */
213 + /* wait for data transfer to complete */
214 + /* rely on the interrupt handling bit */
216 + while (timeout-- && !(*MCF_I2C_I2SR & MCF_I2C_I2SR_IIF))
219 + printk("%s - I2C IIF never set. Timeout is %d \n", __FUNCTION__,
223 + /* reset the interrupt bit */
224 + *MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;
237 + * Generate I2C start or repeat start signal
238 + * Combine the 7 bit target_address and the R/W bit and put it onto the I2C bus
240 +static int coldfire_i2c_start(const char read_write, const u16 target_address, const enum I2C_START_TYPE start_type) {
244 + /* printk(">>> %s START TYPE %s \n", __FUNCTION__,
245 + start_type == FIRST_START ? "FIRST_START":"REPEAT_START");*/
247 + *MCF_I2C_I2CR |= MCF_I2C_I2CR_IEN;
249 + if (start_type == FIRST_START) {
250 + /* Make sure the I2C bus is idle */
251 + timeout = 500; /* 500us timeout */
252 + while (timeout-- && (*MCF_I2C_I2SR & MCF_I2C_I2SR_IBB))
254 + if (timeout <= 0) {
255 + printk("%s - I2C bus always busy in the past 500us timeout is %d \n", __FUNCTION__, timeout);
258 + /* generate a START and put the I2C module into MASTER TX mode*/
259 + *MCF_I2C_I2CR |= (MCF_I2C_I2CR_MSTA | MCF_I2C_I2CR_MTX);
261 + /* wait for bus busy to be set */
263 + while (timeout-- && !(*MCF_I2C_I2SR & MCF_I2C_I2SR_IBB))
265 + if (timeout <= 0) {
266 + printk("%s - I2C bus is never busy after START. Timeout is %d \n", __FUNCTION__, timeout);
271 + /* this is repeat START */
272 + udelay(500); /* need some delay before repeat start */
273 + *MCF_I2C_I2CR |= (MCF_I2C_I2CR_MSTA | MCF_I2C_I2CR_RSTA);
277 + /* combine the R/W bit and the 7 bit target address and put it onto
279 + *MCF_I2C_I2DR = ((target_address & 0x7F) << 1) | (read_write == I2C_SMBUS_WRITE ? 0x00 : 0x01);
281 + /* wait for bus transfer to complete */
282 + /* when one byte transfer is completed, IIF set at the faling edge of
285 + while (timeout-- && !(*MCF_I2C_I2SR & MCF_I2C_I2SR_IIF))
288 + printk("%s - I2C IIF never set. Timeout is %d \n", __FUNCTION__, timeout);
292 + /* reset the interrupt bit */
293 + *MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;
303 + * 5282 SMBUS supporting functions
306 +static s32 coldfire_i2c_access(struct i2c_adapter *adap, u16 addr,
307 + unsigned short flags, char read_write,
308 + u8 command, int size, union i2c_smbus_data *data)
311 + u8 rxData, tempRxData[2];
314 + case I2C_SMBUS_QUICK:
315 + rc = coldfire_i2c_start(read_write, addr, FIRST_START); /* generate START */
317 + case I2C_SMBUS_BYTE:
318 + rc = coldfire_i2c_start(read_write, addr, FIRST_START);
319 + *MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK; /*generate NA */
320 + if (read_write == I2C_SMBUS_WRITE)
321 + rc += coldfire_write_data(command);
323 + coldfire_read_data(&rxData, NACK);/*dummy read*/
324 + rc += coldfire_read_data(&rxData, NACK);
325 + data->byte = rxData;
327 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_TXAK; /* reset ACK bit */
329 + case I2C_SMBUS_BYTE_DATA:
330 + rc = coldfire_i2c_start(I2C_SMBUS_WRITE, addr, FIRST_START);
331 + rc += coldfire_write_data(command);
332 + if (read_write == I2C_SMBUS_WRITE)
333 + rc += coldfire_write_data(data->byte);
335 + /* This is SMBus READ Byte Data Request.
336 + Perform REPEAT START */
337 + rc += coldfire_i2c_start(I2C_SMBUS_READ, addr,
339 + coldfire_read_data(&rxData, ACK);/* dummy read*/
340 + /* Disable Acknowledge, generate STOP after
341 + next byte transfer */
342 + rc += coldfire_read_data(&rxData, NACK);
343 + data->byte = rxData;
345 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_TXAK;/* reset to normal ACk */
347 + case I2C_SMBUS_PROC_CALL:
348 + case I2C_SMBUS_WORD_DATA:
349 + dev_info(&adap->dev, "size = I2C_SMBUS_WORD_DATA \n");
350 + rc = coldfire_i2c_start(I2C_SMBUS_WRITE, addr,
352 + rc += coldfire_write_data(command);
353 + if (read_write == I2C_SMBUS_WRITE) {
354 + rc += coldfire_write_data(data->word & 0x00FF);
355 + rc += coldfire_write_data((data->word & 0x00FF) >> 8);
357 + /* This is SMBUS READ WORD request.
358 + Peform REPEAT START */
359 + rc += coldfire_i2c_start(I2C_SMBUS_READ, addr,
361 + coldfire_read_data(&rxData, ACK);/* dummy read*/
362 + /* Disable Acknowledge, generate STOP after
363 + next byte transfer */
364 + /* read the MS byte from the device */
365 + rc += coldfire_read_data(&rxData, NACK);
366 + tempRxData[1] = rxData;
367 + /* read the LS byte from the device */
368 + rc += coldfire_read_data(&rxData, NACK);
369 + tempRxData[0] = rxData;
370 + /* the host driver expect little endian
371 + convention. Swap the byte */
372 + data->word = (tempRxData[0] << 8)|tempRxData[1];
374 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_TXAK;
376 + case I2C_SMBUS_BLOCK_DATA:
380 + printk("Unsupported I2C size \n");
385 + /* Generate a STOP and put I2C module into slave mode */
386 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MSTA;
388 + /* restore interrupt */
389 + *MCF_I2C_I2CR |= MCF_I2C_I2CR_IIEN;
399 + * List the SMBUS functions supported by this I2C adaptor
400 + * Also tell the I2C Subsystem that we are able of master_xfer()
402 +static u32 coldfire_func(struct i2c_adapter *adapter)
404 + return(I2C_FUNC_SMBUS_QUICK |
405 + I2C_FUNC_SMBUS_BYTE |
406 + I2C_FUNC_SMBUS_PROC_CALL |
407 + I2C_FUNC_SMBUS_BYTE_DATA |
408 + I2C_FUNC_SMBUS_WORD_DATA |
410 + I2C_FUNC_SMBUS_BLOCK_DATA);
413 +static int coldfire_i2c_master(struct i2c_adapter *adap,struct i2c_msg *msgs,
424 + /* disable the IRQ, we are doing polling */
425 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_IIEN;
427 + dev_dbg(&adap->dev,"Num of actions: %d\n", num);
429 + for (i = 0; !err && i < num; i++) {
435 + dev_dbg(&adap->dev,"p->len == 0!\n");
439 + * Generate a new Start, if the target address differs from
440 + * the last target, generate a stop in this case first
442 + if(p->addr != lastaddr)
444 + err = coldfire_do_first_start(p->addr,p->flags);
447 + dev_dbg(&adap->dev,"First Init failed!\n");
452 + else if((p->flags & I2C_M_RD) != lastop)
455 + * If the Operational Mode changed, we need to do this
458 + dev_dbg(&adap->dev,"%s(): Direction changed, was: %d; is now: %d\n", __FUNCTION__, lastop, p->flags & I2C_M_RD);
460 + /* Last op was an read, now it's write: complete stop
462 + if (lastop & I2C_M_RD)
464 + dev_dbg(&adap->dev,"%s(): The device is in read state, we must reset!\n", __FUNCTION__);
465 + if((err = coldfire_do_first_start(p->addr,p->flags)))
470 + dev_dbg(&adap->dev,"%s(): We switchted to read mode\n",__FUNCTION__);
471 + if((err = coldfire_i2c_start((p->flags & I2C_M_RD) ? I2C_SMBUS_READ : I2C_SMBUS_WRITE,
472 + p->addr, REPEAT_START)))
476 + lastop = p->flags & I2C_M_RD; /* Save the last op */
479 + if (p->flags & I2C_M_RD)
482 + * When ever we get here, a new session was activated,
483 + * so read a dummy byte
485 + coldfire_read_data(&dummyRead, ACK);
487 + * read p->len -1 bytes with ACK to the slave,
488 + * read the last byte without the ACK, to inform him
489 + * about the stop afterwards
492 + while(!err && (ic < p->len-1 ))
494 + err = coldfire_read_data(p->buf+ic, ACK );
498 + err = coldfire_read_data(p->buf+ic, NACK);
499 + dev_dbg(&coldfire_adapter.dev,"read: %2x\n",p->buf[ic]);
504 + dev_dbg(&coldfire_adapter.dev,"writing: 0x %2x %2x\n", p->buf[0], p->buf[1]);
507 + * Write data to the slave
509 + for(ic=0; !err && ic < p->len; ic++)
511 + err = coldfire_write_data(p->buf[ic]);
514 + dev_dbg(&coldfire_adapter.dev, "Failed to write data\n");
521 + * Put the device into slave mode to enable the STOP Generation
522 + * (the RTC needs this)
524 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MSTA;
526 + *MCF_I2C_I2CR &= ~MCF_I2C_I2CR_TXAK; /* reset the ACK bit */
528 + /* restore interrupt */
529 + *MCF_I2C_I2CR |= MCF_I2C_I2CR_IIEN;
531 + /* Return the number of messages processed, or the error code. */
539 + * Initalize the 5282 I2C module
540 + * Disable the 5282 I2C interrupt capability. Just use callback
543 +static int __init i2c_coldfire_init(void)
548 +#if defined(CONFIG_M532x) || defined(CONFIG_M5445X)
550 + * Initialize the GPIOs for I2C
552 + MCF_GPIO_PAR_FECI2C |= (0
553 + | MCF_GPIO_PAR_FECI2C_PAR_SDA(3)
554 + | MCF_GPIO_PAR_FECI2C_PAR_SCL(3));
555 +#elif defined(CONFIG_M5253)
558 + /* GPIO Bit 41 = SCL0, Bit 42 = SDA0 */
559 + reg = (volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1FUNC);
560 + *reg &= 0xFFFFF9FF;
563 + /* Initialize PASP0 and PASP1 to I2C functions, 5282 user guide 26-19 */
564 + /* Port AS Pin Assignment Register (PASPAR) */
565 + /* PASPA1 = 11 = AS1 pin is I2C SDA */
566 + /* PASPA0 = 11 = AS0 pin is I2C SCL */
567 + *MCF_GPIO_PASPAR |= 0x000F; /* u16 declaration */
571 + /* Set transmission frequency 0x15 = ~100kHz */
572 + *MCF_I2C_I2FDR = 0x15;
574 + /* set the 5282 I2C slave address though we never use it */
575 + *MCF_I2C_I2ADR = 0x6A;
577 + /* Enable I2C module and if IBB is set, do the special initialzation */
578 + /* procedures as are documented at the 5282 User Guide page 24-11 */
579 + *MCF_I2C_I2CR |= MCF_I2C_I2CR_IEN;
580 + if ((*MCF_I2C_I2SR & MCF_I2C_I2SR_IBB) == 1) {
581 + printk("%s - do special 5282 I2C init procedures \n",
583 + *MCF_I2C_I2CR = 0x00;
584 + *MCF_I2C_I2CR = 0xA0;
585 + dummyRead = *MCF_I2C_I2DR;
586 + *MCF_I2C_I2SR = 0x00;
587 + *MCF_I2C_I2CR = 0x00;
590 + /* default I2C mode is - slave and receive */
591 + *MCF_I2C_I2CR &= ~(MCF_I2C_I2CR_MSTA | MCF_I2C_I2CR_MTX);
593 + coldfire_adapter.dev.parent = &platform_bus;
594 + retval = i2c_add_adapter(&coldfire_adapter);
597 + printk("%s - return code is: %d \n", __FUNCTION__, retval);
604 + * I2C module exit function
607 +static void __exit i2c_coldfire_exit(void)
609 + /* disable I2C and Interrupt */
610 + *MCF_I2C_I2CR &= ~(MCF_I2C_I2CR_IEN | MCF_I2C_I2CR_IIEN);
611 + i2c_del_adapter(&coldfire_adapter);
616 +MODULE_AUTHOR("Derek CL Cheung <derek.cheung@sympatico.ca>");
617 +MODULE_DESCRIPTION("MCF5282 I2C adaptor");
618 +MODULE_LICENSE("GPL");
620 +module_init(i2c_coldfire_init);
621 +module_exit(i2c_coldfire_exit);
623 +++ b/drivers/i2c/busses/i2c-mcf.h
626 + i2c-mcf.h - header file for i2c-mcf.c
628 + Copyright (c) 2005, Derek CL Cheung <derek.cheung@sympatico.ca>
629 + <http://www3.sympatico.ca/derek.cheung>
631 + Copyright (c) 2006-2007, emlix
632 + Sebastian Hess <sh@emlix.com>
634 + Copyright (c) 2006-2007 Freescale Semiconductor, Inc
635 + Yaroslav Vinogradov <yaroslav.vinogradov@freescale.com>
636 + Matt Waddel <Matt.Waddel@freescale.com>
638 + This program is free software; you can redistribute it and/or modify
639 + it under the terms of the GNU General Public License as published by
640 + the Free Software Foundation; either version 2 of the License, or
641 + (at your option) any later version.
643 + This program is distributed in the hope that it will be useful,
644 + but WITHOUT ANY WARRANTY; without even the implied warranty of
645 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
646 + GNU General Public License for more details.
648 + You should have received a copy of the GNU General Public License
649 + along with this program; if not, write to the Free Software
650 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
654 + Initial Release - developed on uClinux with 2.6.9 kernel
656 + Modified to be more generic and added support for
661 +#ifndef __I2C_MCF_H__
662 +#define __I2C_MCF_H__
664 +enum I2C_START_TYPE { FIRST_START, REPEAT_START };
665 +enum I2C_ACK_TYPE { ACK, NACK};
667 +/* Function prototypes */
668 +static u32 coldfire_func(struct i2c_adapter *adapter);
669 +static s32 coldfire_i2c_access(struct i2c_adapter *adap, u16 address,
670 + unsigned short flags, char read_write,
671 + u8 command, int size, union i2c_smbus_data *data);
672 +static int coldfire_write_data(const u8 data);
673 +static int coldfire_i2c_start(const char read_write, const u16 target_address, const enum I2C_START_TYPE i2c_start);
674 +static int coldfire_read_data(u8 * const rxData, const enum I2C_ACK_TYPE ackType);
675 +static int coldfire_i2c_master(struct i2c_adapter *adap,struct i2c_msg *msgs, int num);
676 +void dumpReg(char *, u16 addr, u8 data);
678 +#define MCF_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01)
679 +#define MCF_I2C_I2FDR_IC(x) (((x)&0x3F))
681 +/* I2C Control Register */
682 +#define MCF_I2C_I2CR_IEN (0x80) /* I2C enable */
683 +#define MCF_I2C_I2CR_IIEN (0x40) /* interrupt enable */
684 +#define MCF_I2C_I2CR_MSTA (0x20) /* master/slave mode */
685 +#define MCF_I2C_I2CR_MTX (0x10) /* transmit/receive mode */
686 +#define MCF_I2C_I2CR_TXAK (0x08) /* transmit acknowledge enable */
687 +#define MCF_I2C_I2CR_RSTA (0x04) /* repeat start */
689 +/* I2C Status Register */
690 +#define MCF_I2C_I2SR_ICF (0x80) /* data transfer bit */
691 +#define MCF_I2C_I2SR_IAAS (0x40) /* I2C addressed as a slave */
692 +#define MCF_I2C_I2SR_IBB (0x20) /* I2C bus busy */
693 +#define MCF_I2C_I2SR_IAL (0x10) /* aribitration lost */
694 +#define MCF_I2C_I2SR_SRW (0x04) /* slave read/write */
695 +#define MCF_I2C_I2SR_IIF (0x02) /* I2C interrupt */
696 +#define MCF_I2C_I2SR_RXAK (0x01) /* received acknowledge */
698 +/********************************************************************/
699 +#endif /* __I2C_MCF_H__ */