^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * I2C bus driver for the SH7760 I2C Interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * licensed under the terms outlined in the file COPYING.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/i2c-sh7760.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define I2CSCR 0x0 /* slave ctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define I2CMCR 0x4 /* master ctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define I2CSSR 0x8 /* slave status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define I2CMSR 0xC /* master status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define I2CSIER 0x10 /* slave irq enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define I2CMIER 0x14 /* master irq enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define I2CCCR 0x18 /* clock dividers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define I2CSAR 0x1c /* slave address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define I2CMAR 0x20 /* master address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define I2CRXTX 0x24 /* data port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define I2CFCR 0x28 /* fifo control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define I2CFSR 0x2C /* fifo status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define I2CFIER 0x30 /* fifo irq enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define I2CRFDR 0x34 /* rx fifo count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define I2CTFDR 0x38 /* tx fifo count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define REGSIZE 0x3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MCR_MDBS 0x80 /* non-fifo mode switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MCR_FSCL 0x40 /* override SCL pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MCR_FSDA 0x20 /* override SDA pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MCR_OBPC 0x10 /* override pins */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MCR_MIE 0x08 /* master if enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MCR_TSBE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MCR_FSB 0x02 /* force stop bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MCR_ESG 0x01 /* en startbit gen. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MSR_MNR 0x40 /* nack received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MSR_MAL 0x20 /* arbitration lost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MSR_MST 0x10 /* sent a stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MSR_MDE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MSR_MDT 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define MSR_MDR 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MSR_MAT 0x01 /* slave addr xfer done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MIE_MNRE 0x40 /* nack irq en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MIE_MALE 0x20 /* arblos irq en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MIE_MSTE 0x10 /* stop irq en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MIE_MDEE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MIE_MDTE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MIE_MDRE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MIE_MATE 0x01 /* address sent irq en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define FCR_RFRST 0x02 /* reset rx fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define FCR_TFRST 0x01 /* reset tx fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define FSR_TEND 0x04 /* last byte sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define FSR_RDF 0x02 /* rx fifo trigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define FSR_TDFE 0x01 /* tx fifo empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define FIER_TEIE 0x04 /* tx fifo empty irq en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define FIER_RXIE 0x02 /* rx fifo trig irq en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define FIER_TXIE 0x01 /* tx fifo trig irq en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define FIFO_SIZE 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct cami2c {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) void __iomem *iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct i2c_adapter adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* message processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct i2c_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IDF_SEND 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define IDF_RECV 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IDF_STOP 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define IDS_DONE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define IDS_ARBLOST 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define IDS_NACK 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct completion xfer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct resource *ioarea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static inline void OUT32(struct cami2c *cam, int reg, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __raw_writel(val, (unsigned long)cam->iobase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline unsigned long IN32(struct cami2c *cam, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return __raw_readl((unsigned long)cam->iobase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static irqreturn_t sh7760_i2c_irq(int irq, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct cami2c *id = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct i2c_msg *msg = id->msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) char *data = msg->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned long msr, fsr, fier, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) msr = IN32(id, I2CMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) fsr = IN32(id, I2CFSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* arbitration lost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (msr & MSR_MAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) OUT32(id, I2CMCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) OUT32(id, I2CSCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) OUT32(id, I2CSAR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) id->status |= IDS_DONE | IDS_ARBLOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (msr & MSR_MNR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* NACK handling is very screwed up. After receiving a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * NAK IRQ one has to wait a bit before writing to any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * registers, or the ctl will lock up. After that delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * do a normal i2c stop. Then wait at least 1 ms before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * attempting another transfer or ctl will stop working
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) udelay(100); /* wait or risk ctl hang */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) OUT32(id, I2CFIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) OUT32(id, I2CMIER, MIE_MSTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) OUT32(id, I2CSCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) OUT32(id, I2CSAR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) id->status |= IDS_NACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) msr &= ~MSR_MAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) fsr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* In some cases the MST bit is also set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* i2c-stop was sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (msr & MSR_MST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) id->status |= IDS_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* i2c slave addr was sent; set to "normal" operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (msr & MSR_MAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) OUT32(id, I2CMCR, MCR_MIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) fier = IN32(id, I2CFIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (fsr & FSR_RDF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) len = IN32(id, I2CRFDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (msg->len <= len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (id->flags & IDF_STOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) OUT32(id, I2CFIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* manual says: wait >= 0.5 SCL times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* next int should be MST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) id->status |= IDS_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* keep the RDF bit: ctrl holds SCL low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * until the setup for the next i2c_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * clears this bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) fsr &= ~FSR_RDF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) while (msg->len && len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *data++ = IN32(id, I2CRXTX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) msg->len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (msg->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) len = (msg->len >= FIFO_SIZE) ? FIFO_SIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) : msg->len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xf) << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) } else if (id->flags & IDF_SEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if ((fsr & FSR_TEND) && (msg->len < 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (id->flags & IDF_STOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) id->status |= IDS_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* keep the TEND bit: ctl holds SCL low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * until the setup for the next i2c_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * clears this bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) fsr &= ~FSR_TEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (fsr & FSR_TDFE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) while (msg->len && (IN32(id, I2CTFDR) < FIFO_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) OUT32(id, I2CRXTX, *data++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) msg->len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (msg->len < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) fier &= ~FIER_TXIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) OUT32(id, I2CFIER, fier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) len = (msg->len >= FIFO_SIZE) ? 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) OUT32(id, I2CFCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) FCR_RFRST | ((len & 3) << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (id->status & IDS_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) OUT32(id, I2CMIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) OUT32(id, I2CFIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) id->msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) complete(&id->xfer_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* clear status flags and ctrl resumes work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) OUT32(id, I2CMSR, ~msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) OUT32(id, I2CFSR, ~fsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) OUT32(id, I2CSSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* prepare and start a master receive operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void sh7760_i2c_mrecv(struct cami2c *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) id->flags |= IDF_RECV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* set the slave addr reg; otherwise rcv wont work! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) OUT32(id, I2CSAR, 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) OUT32(id, I2CMAR, (id->msg->addr << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* adjust rx fifo trigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (id->msg->len >= FIFO_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) len = FIFO_SIZE - 1; /* trigger at fifo full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) len = id->msg->len - 1; /* trigger before all received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xF) << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) OUT32(id, I2CMSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) OUT32(id, I2CFIER, FIER_RXIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* prepare and start a master send operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static void sh7760_i2c_msend(struct cami2c *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) id->flags |= IDF_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* set the slave addr reg; otherwise xmit wont work! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) OUT32(id, I2CSAR, 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) OUT32(id, I2CMAR, (id->msg->addr << 1) | 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* adjust tx fifo trigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (id->msg->len >= FIFO_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) len = 2; /* trig: 2 bytes left in TX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) len = 0; /* trig: 8 bytes left in TX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) OUT32(id, I2CFCR, FCR_RFRST | ((len & 3) << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) while (id->msg->len && IN32(id, I2CTFDR) < FIFO_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) OUT32(id, I2CRXTX, *(id->msg->buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) (id->msg->len)--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) (id->msg->buf)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) OUT32(id, I2CMSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) OUT32(id, I2CFSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) OUT32(id, I2CFIER, FIER_TEIE | (id->msg->len ? FIER_TXIE : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static inline int sh7760_i2c_busy_check(struct cami2c *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return (IN32(id, I2CMCR) & MCR_FSDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static int sh7760_i2c_master_xfer(struct i2c_adapter *adap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct i2c_msg *msgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct cami2c *id = adap->algo_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int i, retr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (sh7760_i2c_busy_check(id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dev_err(&adap->dev, "sh7760-i2c%d: bus busy!\n", adap->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) while (i < num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) retr = adap->retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) id->flags = ((i == (num-1)) ? IDF_STOP : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) id->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) id->msg = msgs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) init_completion(&id->xfer_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (msgs->flags & I2C_M_RD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) sh7760_i2c_mrecv(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sh7760_i2c_msend(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) wait_for_completion(&id->xfer_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (id->status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) num = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (id->status & IDS_NACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* wait a bit or i2c module stops working */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) num = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (id->status & IDS_ARBLOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (retr--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mdelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) num = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) msgs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) id->msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) id->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) id->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) OUT32(id, I2CMCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) OUT32(id, I2CMSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) OUT32(id, I2CMIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) OUT32(id, I2CFIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* reset slave module registers too: master mode enables slave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * module for receive ops (ack, data). Without this reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * eternal bus activity might be reported after NACK / ARBLOST.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) OUT32(id, I2CSCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) OUT32(id, I2CSAR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) OUT32(id, I2CSSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static u32 sh7760_i2c_func(struct i2c_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static const struct i2c_algorithm sh7760_i2c_algo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .master_xfer = sh7760_i2c_master_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .functionality = sh7760_i2c_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* calculate CCR register setting for a desired scl clock. SCL clock is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * derived from I2C module clock (iclk) which in turn is derived from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * peripheral module clock (mclk, usually around 33MHz):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * iclk = mclk/(CDF + 1). iclk must be < 20MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * scl = iclk/(SCGD*8 + 20).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int calc_CCR(unsigned long scl_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct clk *mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) unsigned long mck, m1, dff, odff, iclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) signed char cdf, cdfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int scgd, scgdm, scgds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) mclk = clk_get(NULL, "peripheral_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (IS_ERR(mclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return PTR_ERR(mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mck = mclk->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) clk_put(mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) odff = scl_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) scgdm = cdfm = m1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) for (cdf = 3; cdf >= 0; cdf--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) iclk = mck / (1 + cdf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (iclk >= 20000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) scgds = ((iclk / scl_hz) - 20) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) m1 = iclk / (20 + (scgd << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dff = abs(scl_hz - m1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (dff < odff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) odff = dff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) cdfm = cdf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) scgdm = scgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* fail if more than 25% off of requested SCL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (odff > (scl_hz >> 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* create a CCR register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return ((scgdm << 2) | cdfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int sh7760_i2c_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct sh7760_i2c_platdata *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct cami2c *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) pd = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!pd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev_err(&pdev->dev, "no platform_data!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) id = kzalloc(sizeof(struct cami2c), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dev_err(&pdev->dev, "no mem for private data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_err(&pdev->dev, "no mmio resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) id->ioarea = request_mem_region(res->start, REGSIZE, pdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (!id->ioarea) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) dev_err(&pdev->dev, "mmio already reserved\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) id->iobase = ioremap(res->start, REGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (!id->iobase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dev_err(&pdev->dev, "cannot ioremap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) id->irq = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) id->adap.nr = pdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) id->adap.algo = &sh7760_i2c_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) id->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) id->adap.retries = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) id->adap.algo_data = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) id->adap.dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) snprintf(id->adap.name, sizeof(id->adap.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) "SH7760 I2C at %08lx", (unsigned long)res->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) OUT32(id, I2CMCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) OUT32(id, I2CMSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) OUT32(id, I2CMIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) OUT32(id, I2CMAR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) OUT32(id, I2CSIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) OUT32(id, I2CSAR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) OUT32(id, I2CSCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) OUT32(id, I2CSSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) OUT32(id, I2CFIER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) OUT32(id, I2CFSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = calc_CCR(pd->speed_khz * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) pd->speed_khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) OUT32(id, I2CCCR, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (request_irq(id->irq, sh7760_i2c_irq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) SH7760_I2C_DEVNAME, id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dev_err(&pdev->dev, "cannot get irq %d\n", id->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = i2c_add_numbered_adapter(&id->adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) goto out4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) platform_set_drvdata(pdev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dev_info(&pdev->dev, "%d kHz mmio %08x irq %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) pd->speed_khz, res->start, id->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) out4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) free_irq(id->irq, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) iounmap(id->iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) release_resource(id->ioarea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) kfree(id->ioarea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) kfree(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static int sh7760_i2c_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct cami2c *id = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) i2c_del_adapter(&id->adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) free_irq(id->irq, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) iounmap(id->iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) release_resource(id->ioarea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) kfree(id->ioarea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) kfree(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static struct platform_driver sh7760_i2c_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .name = SH7760_I2C_DEVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .probe = sh7760_i2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .remove = sh7760_i2c_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) module_platform_driver(sh7760_i2c_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) MODULE_DESCRIPTION("SH7760 I2C bus driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");