0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <linux/delay.h>
0037 #include <linux/init.h>
0038 #include <linux/io.h>
0039 #include <linux/ioport.h>
0040 #include <linux/kernel.h>
0041 #include <linux/module.h>
0042
0043 #include <linux/i2c.h>
0044 #include <linux/i2c-algo-pcf.h>
0045
0046 #include <asm/amigahw.h>
0047 #include <asm/amigaints.h>
0048 #include <linux/zorro.h>
0049
0050 #include "../algos/i2c-algo-pcf.h"
0051
0052 struct icy_i2c {
0053 struct i2c_adapter adapter;
0054
0055 void __iomem *reg_s0;
0056 void __iomem *reg_s1;
0057 struct i2c_client *ltc2990_client;
0058 };
0059
0060
0061
0062
0063 static void icy_pcf_setpcf(void *data, int ctl, int val)
0064 {
0065 struct icy_i2c *i2c = (struct icy_i2c *)data;
0066
0067 u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
0068
0069 z_writeb(val, address);
0070 }
0071
0072 static int icy_pcf_getpcf(void *data, int ctl)
0073 {
0074 struct icy_i2c *i2c = (struct icy_i2c *)data;
0075
0076 u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
0077
0078 return z_readb(address);
0079 }
0080
0081 static int icy_pcf_getown(void *data)
0082 {
0083 return 0x55;
0084 }
0085
0086 static int icy_pcf_getclock(void *data)
0087 {
0088 return 0x1c;
0089 }
0090
0091 static void icy_pcf_waitforpin(void *data)
0092 {
0093 usleep_range(50, 150);
0094 }
0095
0096
0097
0098
0099 static unsigned short const icy_ltc2990_addresses[] = {
0100 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END
0101 };
0102
0103
0104
0105
0106
0107
0108
0109
0110 static const u32 icy_ltc2990_meas_mode[] = {0, 3};
0111
0112 static const struct property_entry icy_ltc2990_props[] = {
0113 PROPERTY_ENTRY_U32_ARRAY("lltc,meas-mode", icy_ltc2990_meas_mode),
0114 { }
0115 };
0116
0117 static const struct software_node icy_ltc2990_node = {
0118 .properties = icy_ltc2990_props,
0119 };
0120
0121 static int icy_probe(struct zorro_dev *z,
0122 const struct zorro_device_id *ent)
0123 {
0124 struct icy_i2c *i2c;
0125 struct i2c_algo_pcf_data *algo_data;
0126 struct i2c_board_info ltc2990_info = {
0127 .type = "ltc2990",
0128 .swnode = &icy_ltc2990_node,
0129 };
0130
0131 i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL);
0132 if (!i2c)
0133 return -ENOMEM;
0134
0135 algo_data = devm_kzalloc(&z->dev, sizeof(*algo_data), GFP_KERNEL);
0136 if (!algo_data)
0137 return -ENOMEM;
0138
0139 dev_set_drvdata(&z->dev, i2c);
0140 i2c->adapter.dev.parent = &z->dev;
0141 i2c->adapter.owner = THIS_MODULE;
0142
0143 i2c->adapter.algo_data = algo_data;
0144 strscpy(i2c->adapter.name, "ICY I2C Zorro adapter",
0145 sizeof(i2c->adapter.name));
0146
0147 if (!devm_request_mem_region(&z->dev,
0148 z->resource.start,
0149 4, i2c->adapter.name))
0150 return -ENXIO;
0151
0152
0153 i2c->reg_s0 = ZTWO_VADDR(z->resource.start);
0154 i2c->reg_s1 = ZTWO_VADDR(z->resource.start + 2);
0155
0156 algo_data->data = i2c;
0157 algo_data->setpcf = icy_pcf_setpcf;
0158 algo_data->getpcf = icy_pcf_getpcf;
0159 algo_data->getown = icy_pcf_getown;
0160 algo_data->getclock = icy_pcf_getclock;
0161 algo_data->waitforpin = icy_pcf_waitforpin;
0162
0163 if (i2c_pcf_add_bus(&i2c->adapter)) {
0164 dev_err(&z->dev, "i2c_pcf_add_bus() failed\n");
0165 return -ENXIO;
0166 }
0167
0168 dev_info(&z->dev, "ICY I2C controller at %pa, IRQ not implemented\n",
0169 &z->resource.start);
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 i2c->ltc2990_client = i2c_new_scanned_device(&i2c->adapter,
0181 <c2990_info,
0182 icy_ltc2990_addresses,
0183 NULL);
0184 return 0;
0185 }
0186
0187 static void icy_remove(struct zorro_dev *z)
0188 {
0189 struct icy_i2c *i2c = dev_get_drvdata(&z->dev);
0190
0191 i2c_unregister_device(i2c->ltc2990_client);
0192 i2c_del_adapter(&i2c->adapter);
0193 }
0194
0195 static const struct zorro_device_id icy_zorro_tbl[] = {
0196 { ZORRO_ID(VMC, 15, 0), },
0197 { 0 }
0198 };
0199
0200 MODULE_DEVICE_TABLE(zorro, icy_zorro_tbl);
0201
0202 static struct zorro_driver icy_driver = {
0203 .name = "i2c-icy",
0204 .id_table = icy_zorro_tbl,
0205 .probe = icy_probe,
0206 .remove = icy_remove,
0207 };
0208
0209 module_driver(icy_driver,
0210 zorro_register_driver,
0211 zorro_unregister_driver);
0212
0213 MODULE_AUTHOR("Max Staudt <max@enpas.org>");
0214 MODULE_DESCRIPTION("I2C bus via PCF8584 on ICY Zorro card");
0215 MODULE_LICENSE("GPL v2");