xref: /qemu/hw/i2c/ppc4xx_i2c.c (revision 3b09bb0fb9bc03f3897da4940ba2fb808c00c038)
165ca801bSBALATON Zoltan /*
265ca801bSBALATON Zoltan  * PPC4xx I2C controller emulation
365ca801bSBALATON Zoltan  *
465ca801bSBALATON Zoltan  * Copyright (c) 2007 Jocelyn Mayer
565ca801bSBALATON Zoltan  *
665ca801bSBALATON Zoltan  * Permission is hereby granted, free of charge, to any person obtaining a copy
765ca801bSBALATON Zoltan  * of this software and associated documentation files (the "Software"), to deal
865ca801bSBALATON Zoltan  * in the Software without restriction, including without limitation the rights
965ca801bSBALATON Zoltan  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1065ca801bSBALATON Zoltan  * copies of the Software, and to permit persons to whom the Software is
1165ca801bSBALATON Zoltan  * furnished to do so, subject to the following conditions:
1265ca801bSBALATON Zoltan  *
1365ca801bSBALATON Zoltan  * The above copyright notice and this permission notice shall be included in
1465ca801bSBALATON Zoltan  * all copies or substantial portions of the Software.
1565ca801bSBALATON Zoltan  *
1665ca801bSBALATON Zoltan  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1765ca801bSBALATON Zoltan  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1865ca801bSBALATON Zoltan  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1965ca801bSBALATON Zoltan  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2065ca801bSBALATON Zoltan  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2165ca801bSBALATON Zoltan  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2265ca801bSBALATON Zoltan  * THE SOFTWARE.
2365ca801bSBALATON Zoltan  */
2465ca801bSBALATON Zoltan 
2565ca801bSBALATON Zoltan #include "qemu/osdep.h"
2665ca801bSBALATON Zoltan #include "qapi/error.h"
2765ca801bSBALATON Zoltan #include "qemu-common.h"
2865ca801bSBALATON Zoltan #include "cpu.h"
2965ca801bSBALATON Zoltan #include "hw/hw.h"
30*3b09bb0fSBALATON Zoltan #include "hw/i2c/ppc4xx_i2c.h"
3165ca801bSBALATON Zoltan 
3265ca801bSBALATON Zoltan /*#define DEBUG_I2C*/
3365ca801bSBALATON Zoltan 
34*3b09bb0fSBALATON Zoltan #define PPC4xx_I2C_MEM_SIZE 0x11
3565ca801bSBALATON Zoltan 
36*3b09bb0fSBALATON Zoltan static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size)
3765ca801bSBALATON Zoltan {
38*3b09bb0fSBALATON Zoltan     PPC4xxI2CState *i2c = PPC4xx_I2C(opaque);
39*3b09bb0fSBALATON Zoltan     uint64_t ret;
4065ca801bSBALATON Zoltan 
4165ca801bSBALATON Zoltan #ifdef DEBUG_I2C
4265ca801bSBALATON Zoltan     printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
4365ca801bSBALATON Zoltan #endif
4465ca801bSBALATON Zoltan     switch (addr) {
4565ca801bSBALATON Zoltan     case 0x00:
4665ca801bSBALATON Zoltan         /*i2c_readbyte(&i2c->mdata);*/
4765ca801bSBALATON Zoltan         ret = i2c->mdata;
4865ca801bSBALATON Zoltan         break;
4965ca801bSBALATON Zoltan     case 0x02:
5065ca801bSBALATON Zoltan         ret = i2c->sdata;
5165ca801bSBALATON Zoltan         break;
5265ca801bSBALATON Zoltan     case 0x04:
5365ca801bSBALATON Zoltan         ret = i2c->lmadr;
5465ca801bSBALATON Zoltan         break;
5565ca801bSBALATON Zoltan     case 0x05:
5665ca801bSBALATON Zoltan         ret = i2c->hmadr;
5765ca801bSBALATON Zoltan         break;
5865ca801bSBALATON Zoltan     case 0x06:
5965ca801bSBALATON Zoltan         ret = i2c->cntl;
6065ca801bSBALATON Zoltan         break;
6165ca801bSBALATON Zoltan     case 0x07:
6265ca801bSBALATON Zoltan         ret = i2c->mdcntl;
6365ca801bSBALATON Zoltan         break;
6465ca801bSBALATON Zoltan     case 0x08:
6565ca801bSBALATON Zoltan         ret = i2c->sts;
6665ca801bSBALATON Zoltan         break;
6765ca801bSBALATON Zoltan     case 0x09:
6865ca801bSBALATON Zoltan         ret = i2c->extsts;
6965ca801bSBALATON Zoltan         break;
7065ca801bSBALATON Zoltan     case 0x0A:
7165ca801bSBALATON Zoltan         ret = i2c->lsadr;
7265ca801bSBALATON Zoltan         break;
7365ca801bSBALATON Zoltan     case 0x0B:
7465ca801bSBALATON Zoltan         ret = i2c->hsadr;
7565ca801bSBALATON Zoltan         break;
7665ca801bSBALATON Zoltan     case 0x0C:
7765ca801bSBALATON Zoltan         ret = i2c->clkdiv;
7865ca801bSBALATON Zoltan         break;
7965ca801bSBALATON Zoltan     case 0x0D:
8065ca801bSBALATON Zoltan         ret = i2c->intrmsk;
8165ca801bSBALATON Zoltan         break;
8265ca801bSBALATON Zoltan     case 0x0E:
8365ca801bSBALATON Zoltan         ret = i2c->xfrcnt;
8465ca801bSBALATON Zoltan         break;
8565ca801bSBALATON Zoltan     case 0x0F:
8665ca801bSBALATON Zoltan         ret = i2c->xtcntlss;
8765ca801bSBALATON Zoltan         break;
8865ca801bSBALATON Zoltan     case 0x10:
8965ca801bSBALATON Zoltan         ret = i2c->directcntl;
9065ca801bSBALATON Zoltan         break;
9165ca801bSBALATON Zoltan     default:
9265ca801bSBALATON Zoltan         ret = 0x00;
9365ca801bSBALATON Zoltan         break;
9465ca801bSBALATON Zoltan     }
9565ca801bSBALATON Zoltan #ifdef DEBUG_I2C
96*3b09bb0fSBALATON Zoltan     printf("%s: addr " TARGET_FMT_plx " %02" PRIx64 "\n", __func__, addr, ret);
9765ca801bSBALATON Zoltan #endif
9865ca801bSBALATON Zoltan 
9965ca801bSBALATON Zoltan     return ret;
10065ca801bSBALATON Zoltan }
10165ca801bSBALATON Zoltan 
102*3b09bb0fSBALATON Zoltan static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
103*3b09bb0fSBALATON Zoltan                               unsigned int size)
10465ca801bSBALATON Zoltan {
105*3b09bb0fSBALATON Zoltan     PPC4xxI2CState *i2c = opaque;
10665ca801bSBALATON Zoltan #ifdef DEBUG_I2C
107*3b09bb0fSBALATON Zoltan     printf("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n",
108*3b09bb0fSBALATON Zoltan            __func__, addr, value);
10965ca801bSBALATON Zoltan #endif
11065ca801bSBALATON Zoltan     switch (addr) {
11165ca801bSBALATON Zoltan     case 0x00:
11265ca801bSBALATON Zoltan         i2c->mdata = value;
11365ca801bSBALATON Zoltan         /*i2c_sendbyte(&i2c->mdata);*/
11465ca801bSBALATON Zoltan         break;
11565ca801bSBALATON Zoltan     case 0x02:
11665ca801bSBALATON Zoltan         i2c->sdata = value;
11765ca801bSBALATON Zoltan         break;
11865ca801bSBALATON Zoltan     case 0x04:
11965ca801bSBALATON Zoltan         i2c->lmadr = value;
12065ca801bSBALATON Zoltan         break;
12165ca801bSBALATON Zoltan     case 0x05:
12265ca801bSBALATON Zoltan         i2c->hmadr = value;
12365ca801bSBALATON Zoltan         break;
12465ca801bSBALATON Zoltan     case 0x06:
12565ca801bSBALATON Zoltan         i2c->cntl = value;
12665ca801bSBALATON Zoltan         break;
12765ca801bSBALATON Zoltan     case 0x07:
12865ca801bSBALATON Zoltan         i2c->mdcntl = value & 0xDF;
12965ca801bSBALATON Zoltan         break;
13065ca801bSBALATON Zoltan     case 0x08:
13165ca801bSBALATON Zoltan         i2c->sts &= ~(value & 0x0A);
13265ca801bSBALATON Zoltan         break;
13365ca801bSBALATON Zoltan     case 0x09:
13465ca801bSBALATON Zoltan         i2c->extsts &= ~(value & 0x8F);
13565ca801bSBALATON Zoltan         break;
13665ca801bSBALATON Zoltan     case 0x0A:
13765ca801bSBALATON Zoltan         i2c->lsadr = value;
13865ca801bSBALATON Zoltan         break;
13965ca801bSBALATON Zoltan     case 0x0B:
14065ca801bSBALATON Zoltan         i2c->hsadr = value;
14165ca801bSBALATON Zoltan         break;
14265ca801bSBALATON Zoltan     case 0x0C:
14365ca801bSBALATON Zoltan         i2c->clkdiv = value;
14465ca801bSBALATON Zoltan         break;
14565ca801bSBALATON Zoltan     case 0x0D:
14665ca801bSBALATON Zoltan         i2c->intrmsk = value;
14765ca801bSBALATON Zoltan         break;
14865ca801bSBALATON Zoltan     case 0x0E:
14965ca801bSBALATON Zoltan         i2c->xfrcnt = value & 0x77;
15065ca801bSBALATON Zoltan         break;
15165ca801bSBALATON Zoltan     case 0x0F:
15265ca801bSBALATON Zoltan         i2c->xtcntlss = value;
15365ca801bSBALATON Zoltan         break;
15465ca801bSBALATON Zoltan     case 0x10:
15565ca801bSBALATON Zoltan         i2c->directcntl = value & 0x7;
15665ca801bSBALATON Zoltan         break;
15765ca801bSBALATON Zoltan     }
15865ca801bSBALATON Zoltan }
15965ca801bSBALATON Zoltan 
160*3b09bb0fSBALATON Zoltan static const MemoryRegionOps ppc4xx_i2c_ops = {
161*3b09bb0fSBALATON Zoltan     .read = ppc4xx_i2c_readb,
162*3b09bb0fSBALATON Zoltan     .write = ppc4xx_i2c_writeb,
163*3b09bb0fSBALATON Zoltan     .valid.min_access_size = 1,
164*3b09bb0fSBALATON Zoltan     .valid.max_access_size = 4,
165*3b09bb0fSBALATON Zoltan     .impl.min_access_size = 1,
166*3b09bb0fSBALATON Zoltan     .impl.max_access_size = 1,
16765ca801bSBALATON Zoltan     .endianness = DEVICE_NATIVE_ENDIAN,
16865ca801bSBALATON Zoltan };
16965ca801bSBALATON Zoltan 
170*3b09bb0fSBALATON Zoltan static void ppc4xx_i2c_reset(DeviceState *s)
17165ca801bSBALATON Zoltan {
172*3b09bb0fSBALATON Zoltan     PPC4xxI2CState *i2c = PPC4xx_I2C(s);
17365ca801bSBALATON Zoltan 
17465ca801bSBALATON Zoltan     i2c->mdata = 0x00;
17565ca801bSBALATON Zoltan     i2c->sdata = 0x00;
17665ca801bSBALATON Zoltan     i2c->cntl = 0x00;
17765ca801bSBALATON Zoltan     i2c->mdcntl = 0x00;
17865ca801bSBALATON Zoltan     i2c->sts = 0x00;
17965ca801bSBALATON Zoltan     i2c->extsts = 0x00;
18065ca801bSBALATON Zoltan     i2c->clkdiv = 0x00;
18165ca801bSBALATON Zoltan     i2c->xfrcnt = 0x00;
18265ca801bSBALATON Zoltan     i2c->directcntl = 0x0F;
18365ca801bSBALATON Zoltan }
18465ca801bSBALATON Zoltan 
185*3b09bb0fSBALATON Zoltan static void ppc4xx_i2c_init(Object *o)
18665ca801bSBALATON Zoltan {
187*3b09bb0fSBALATON Zoltan     PPC4xxI2CState *s = PPC4xx_I2C(o);
18865ca801bSBALATON Zoltan 
189*3b09bb0fSBALATON Zoltan     memory_region_init_io(&s->iomem, OBJECT(s), &ppc4xx_i2c_ops, s,
190*3b09bb0fSBALATON Zoltan                           TYPE_PPC4xx_I2C, PPC4xx_I2C_MEM_SIZE);
191*3b09bb0fSBALATON Zoltan     sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
192*3b09bb0fSBALATON Zoltan     sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
193*3b09bb0fSBALATON Zoltan     s->bus = i2c_init_bus(DEVICE(s), "i2c");
19465ca801bSBALATON Zoltan }
195*3b09bb0fSBALATON Zoltan 
196*3b09bb0fSBALATON Zoltan static void ppc4xx_i2c_class_init(ObjectClass *klass, void *data)
197*3b09bb0fSBALATON Zoltan {
198*3b09bb0fSBALATON Zoltan     DeviceClass *dc = DEVICE_CLASS(klass);
199*3b09bb0fSBALATON Zoltan 
200*3b09bb0fSBALATON Zoltan     dc->reset = ppc4xx_i2c_reset;
201*3b09bb0fSBALATON Zoltan }
202*3b09bb0fSBALATON Zoltan 
203*3b09bb0fSBALATON Zoltan static const TypeInfo ppc4xx_i2c_type_info = {
204*3b09bb0fSBALATON Zoltan     .name = TYPE_PPC4xx_I2C,
205*3b09bb0fSBALATON Zoltan     .parent = TYPE_SYS_BUS_DEVICE,
206*3b09bb0fSBALATON Zoltan     .instance_size = sizeof(PPC4xxI2CState),
207*3b09bb0fSBALATON Zoltan     .instance_init = ppc4xx_i2c_init,
208*3b09bb0fSBALATON Zoltan     .class_init = ppc4xx_i2c_class_init,
209*3b09bb0fSBALATON Zoltan };
210*3b09bb0fSBALATON Zoltan 
211*3b09bb0fSBALATON Zoltan static void ppc4xx_i2c_register_types(void)
212*3b09bb0fSBALATON Zoltan {
213*3b09bb0fSBALATON Zoltan     type_register_static(&ppc4xx_i2c_type_info);
214*3b09bb0fSBALATON Zoltan }
215*3b09bb0fSBALATON Zoltan 
216*3b09bb0fSBALATON Zoltan type_init(ppc4xx_i2c_register_types)
217