0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define nv4e_i2c_bus(p) container_of((p), struct nv4e_i2c_bus, base)
0025 #include "bus.h"
0026
0027 struct nv4e_i2c_bus {
0028 struct nvkm_i2c_bus base;
0029 u32 addr;
0030 };
0031
0032 static void
0033 nv4e_i2c_bus_drive_scl(struct nvkm_i2c_bus *base, int state)
0034 {
0035 struct nv4e_i2c_bus *bus = nv4e_i2c_bus(base);
0036 struct nvkm_device *device = bus->base.pad->i2c->subdev.device;
0037 nvkm_mask(device, bus->addr, 0x2f, state ? 0x21 : 0x01);
0038 }
0039
0040 static void
0041 nv4e_i2c_bus_drive_sda(struct nvkm_i2c_bus *base, int state)
0042 {
0043 struct nv4e_i2c_bus *bus = nv4e_i2c_bus(base);
0044 struct nvkm_device *device = bus->base.pad->i2c->subdev.device;
0045 nvkm_mask(device, bus->addr, 0x1f, state ? 0x11 : 0x01);
0046 }
0047
0048 static int
0049 nv4e_i2c_bus_sense_scl(struct nvkm_i2c_bus *base)
0050 {
0051 struct nv4e_i2c_bus *bus = nv4e_i2c_bus(base);
0052 struct nvkm_device *device = bus->base.pad->i2c->subdev.device;
0053 return !!(nvkm_rd32(device, bus->addr) & 0x00040000);
0054 }
0055
0056 static int
0057 nv4e_i2c_bus_sense_sda(struct nvkm_i2c_bus *base)
0058 {
0059 struct nv4e_i2c_bus *bus = nv4e_i2c_bus(base);
0060 struct nvkm_device *device = bus->base.pad->i2c->subdev.device;
0061 return !!(nvkm_rd32(device, bus->addr) & 0x00080000);
0062 }
0063
0064 static const struct nvkm_i2c_bus_func
0065 nv4e_i2c_bus_func = {
0066 .drive_scl = nv4e_i2c_bus_drive_scl,
0067 .drive_sda = nv4e_i2c_bus_drive_sda,
0068 .sense_scl = nv4e_i2c_bus_sense_scl,
0069 .sense_sda = nv4e_i2c_bus_sense_sda,
0070 .xfer = nvkm_i2c_bit_xfer,
0071 };
0072
0073 int
0074 nv4e_i2c_bus_new(struct nvkm_i2c_pad *pad, int id, u8 drive,
0075 struct nvkm_i2c_bus **pbus)
0076 {
0077 struct nv4e_i2c_bus *bus;
0078
0079 if (!(bus = kzalloc(sizeof(*bus), GFP_KERNEL)))
0080 return -ENOMEM;
0081 *pbus = &bus->base;
0082
0083 nvkm_i2c_bus_ctor(&nv4e_i2c_bus_func, pad, id, &bus->base);
0084 bus->addr = 0x600800 + drive;
0085 return 0;
0086 }