diff options
Diffstat (limited to 'drivers/i2c/chips/isp1301_omap.c')
-rw-r--r-- | drivers/i2c/chips/isp1301_omap.c | 141 |
1 files changed, 55 insertions, 86 deletions
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 4655b794ebe3..28902ebd5539 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
@@ -49,10 +49,9 @@ MODULE_LICENSE("GPL"); | |||
49 | 49 | ||
50 | struct isp1301 { | 50 | struct isp1301 { |
51 | struct otg_transceiver otg; | 51 | struct otg_transceiver otg; |
52 | struct i2c_client client; | 52 | struct i2c_client *client; |
53 | void (*i2c_release)(struct device *dev); | 53 | void (*i2c_release)(struct device *dev); |
54 | 54 | ||
55 | int irq; | ||
56 | int irq_type; | 55 | int irq_type; |
57 | 56 | ||
58 | u32 last_otg_ctrl; | 57 | u32 last_otg_ctrl; |
@@ -138,14 +137,6 @@ static inline void notresponding(struct isp1301 *isp) | |||
138 | 137 | ||
139 | /*-------------------------------------------------------------------------*/ | 138 | /*-------------------------------------------------------------------------*/ |
140 | 139 | ||
141 | /* only two addresses possible */ | ||
142 | #define ISP_BASE 0x2c | ||
143 | static unsigned short normal_i2c[] = { | ||
144 | ISP_BASE, ISP_BASE + 1, | ||
145 | I2C_CLIENT_END }; | ||
146 | |||
147 | I2C_CLIENT_INSMOD; | ||
148 | |||
149 | static struct i2c_driver isp1301_driver; | 140 | static struct i2c_driver isp1301_driver; |
150 | 141 | ||
151 | /* smbus apis are used for portability */ | 142 | /* smbus apis are used for portability */ |
@@ -153,25 +144,25 @@ static struct i2c_driver isp1301_driver; | |||
153 | static inline u8 | 144 | static inline u8 |
154 | isp1301_get_u8(struct isp1301 *isp, u8 reg) | 145 | isp1301_get_u8(struct isp1301 *isp, u8 reg) |
155 | { | 146 | { |
156 | return i2c_smbus_read_byte_data(&isp->client, reg + 0); | 147 | return i2c_smbus_read_byte_data(isp->client, reg + 0); |
157 | } | 148 | } |
158 | 149 | ||
159 | static inline int | 150 | static inline int |
160 | isp1301_get_u16(struct isp1301 *isp, u8 reg) | 151 | isp1301_get_u16(struct isp1301 *isp, u8 reg) |
161 | { | 152 | { |
162 | return i2c_smbus_read_word_data(&isp->client, reg); | 153 | return i2c_smbus_read_word_data(isp->client, reg); |
163 | } | 154 | } |
164 | 155 | ||
165 | static inline int | 156 | static inline int |
166 | isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) | 157 | isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) |
167 | { | 158 | { |
168 | return i2c_smbus_write_byte_data(&isp->client, reg + 0, bits); | 159 | return i2c_smbus_write_byte_data(isp->client, reg + 0, bits); |
169 | } | 160 | } |
170 | 161 | ||
171 | static inline int | 162 | static inline int |
172 | isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) | 163 | isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) |
173 | { | 164 | { |
174 | return i2c_smbus_write_byte_data(&isp->client, reg + 1, bits); | 165 | return i2c_smbus_write_byte_data(isp->client, reg + 1, bits); |
175 | } | 166 | } |
176 | 167 | ||
177 | /*-------------------------------------------------------------------------*/ | 168 | /*-------------------------------------------------------------------------*/ |
@@ -349,10 +340,10 @@ isp1301_defer_work(struct isp1301 *isp, int work) | |||
349 | int status; | 340 | int status; |
350 | 341 | ||
351 | if (isp && !test_and_set_bit(work, &isp->todo)) { | 342 | if (isp && !test_and_set_bit(work, &isp->todo)) { |
352 | (void) get_device(&isp->client.dev); | 343 | (void) get_device(&isp->client->dev); |
353 | status = schedule_work(&isp->work); | 344 | status = schedule_work(&isp->work); |
354 | if (!status && !isp->working) | 345 | if (!status && !isp->working) |
355 | dev_vdbg(&isp->client.dev, | 346 | dev_vdbg(&isp->client->dev, |
356 | "work item %d may be lost\n", work); | 347 | "work item %d may be lost\n", work); |
357 | } | 348 | } |
358 | } | 349 | } |
@@ -1135,7 +1126,7 @@ isp1301_work(struct work_struct *work) | |||
1135 | /* transfer state from otg engine to isp1301 */ | 1126 | /* transfer state from otg engine to isp1301 */ |
1136 | if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { | 1127 | if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { |
1137 | otg_update_isp(isp); | 1128 | otg_update_isp(isp); |
1138 | put_device(&isp->client.dev); | 1129 | put_device(&isp->client->dev); |
1139 | } | 1130 | } |
1140 | #endif | 1131 | #endif |
1141 | /* transfer state from isp1301 to otg engine */ | 1132 | /* transfer state from isp1301 to otg engine */ |
@@ -1143,7 +1134,7 @@ isp1301_work(struct work_struct *work) | |||
1143 | u8 stat = isp1301_clear_latch(isp); | 1134 | u8 stat = isp1301_clear_latch(isp); |
1144 | 1135 | ||
1145 | isp_update_otg(isp, stat); | 1136 | isp_update_otg(isp, stat); |
1146 | put_device(&isp->client.dev); | 1137 | put_device(&isp->client->dev); |
1147 | } | 1138 | } |
1148 | 1139 | ||
1149 | if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { | 1140 | if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { |
@@ -1178,7 +1169,7 @@ isp1301_work(struct work_struct *work) | |||
1178 | } | 1169 | } |
1179 | host_resume(isp); | 1170 | host_resume(isp); |
1180 | // mdelay(10); | 1171 | // mdelay(10); |
1181 | put_device(&isp->client.dev); | 1172 | put_device(&isp->client->dev); |
1182 | } | 1173 | } |
1183 | 1174 | ||
1184 | if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { | 1175 | if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { |
@@ -1187,15 +1178,15 @@ isp1301_work(struct work_struct *work) | |||
1187 | if (!stop) | 1178 | if (!stop) |
1188 | mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); | 1179 | mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); |
1189 | #endif | 1180 | #endif |
1190 | put_device(&isp->client.dev); | 1181 | put_device(&isp->client->dev); |
1191 | } | 1182 | } |
1192 | 1183 | ||
1193 | if (isp->todo) | 1184 | if (isp->todo) |
1194 | dev_vdbg(&isp->client.dev, | 1185 | dev_vdbg(&isp->client->dev, |
1195 | "work done, todo = 0x%lx\n", | 1186 | "work done, todo = 0x%lx\n", |
1196 | isp->todo); | 1187 | isp->todo); |
1197 | if (stop) { | 1188 | if (stop) { |
1198 | dev_dbg(&isp->client.dev, "stop\n"); | 1189 | dev_dbg(&isp->client->dev, "stop\n"); |
1199 | break; | 1190 | break; |
1200 | } | 1191 | } |
1201 | } while (isp->todo); | 1192 | } while (isp->todo); |
@@ -1219,7 +1210,7 @@ static void isp1301_release(struct device *dev) | |||
1219 | { | 1210 | { |
1220 | struct isp1301 *isp; | 1211 | struct isp1301 *isp; |
1221 | 1212 | ||
1222 | isp = container_of(dev, struct isp1301, client.dev); | 1213 | isp = dev_get_drvdata(dev); |
1223 | 1214 | ||
1224 | /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ | 1215 | /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ |
1225 | if (isp->i2c_release) | 1216 | if (isp->i2c_release) |
@@ -1229,15 +1220,15 @@ static void isp1301_release(struct device *dev) | |||
1229 | 1220 | ||
1230 | static struct isp1301 *the_transceiver; | 1221 | static struct isp1301 *the_transceiver; |
1231 | 1222 | ||
1232 | static int isp1301_detach_client(struct i2c_client *i2c) | 1223 | static int __exit isp1301_remove(struct i2c_client *i2c) |
1233 | { | 1224 | { |
1234 | struct isp1301 *isp; | 1225 | struct isp1301 *isp; |
1235 | 1226 | ||
1236 | isp = container_of(i2c, struct isp1301, client); | 1227 | isp = i2c_get_clientdata(i2c); |
1237 | 1228 | ||
1238 | isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); | 1229 | isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); |
1239 | isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); | 1230 | isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); |
1240 | free_irq(isp->irq, isp); | 1231 | free_irq(i2c->irq, isp); |
1241 | #ifdef CONFIG_USB_OTG | 1232 | #ifdef CONFIG_USB_OTG |
1242 | otg_unbind(isp); | 1233 | otg_unbind(isp); |
1243 | #endif | 1234 | #endif |
@@ -1252,7 +1243,7 @@ static int isp1301_detach_client(struct i2c_client *i2c) | |||
1252 | put_device(&i2c->dev); | 1243 | put_device(&i2c->dev); |
1253 | the_transceiver = 0; | 1244 | the_transceiver = 0; |
1254 | 1245 | ||
1255 | return i2c_detach_client(i2c); | 1246 | return 0; |
1256 | } | 1247 | } |
1257 | 1248 | ||
1258 | /*-------------------------------------------------------------------------*/ | 1249 | /*-------------------------------------------------------------------------*/ |
@@ -1285,7 +1276,7 @@ static int isp1301_otg_enable(struct isp1301 *isp) | |||
1285 | isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, | 1276 | isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, |
1286 | INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); | 1277 | INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); |
1287 | 1278 | ||
1288 | dev_info(&isp->client.dev, "ready for dual-role USB ...\n"); | 1279 | dev_info(&isp->client->dev, "ready for dual-role USB ...\n"); |
1289 | 1280 | ||
1290 | return 0; | 1281 | return 0; |
1291 | } | 1282 | } |
@@ -1310,7 +1301,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) | |||
1310 | 1301 | ||
1311 | #ifdef CONFIG_USB_OTG | 1302 | #ifdef CONFIG_USB_OTG |
1312 | isp->otg.host = host; | 1303 | isp->otg.host = host; |
1313 | dev_dbg(&isp->client.dev, "registered host\n"); | 1304 | dev_dbg(&isp->client->dev, "registered host\n"); |
1314 | host_suspend(isp); | 1305 | host_suspend(isp); |
1315 | if (isp->otg.gadget) | 1306 | if (isp->otg.gadget) |
1316 | return isp1301_otg_enable(isp); | 1307 | return isp1301_otg_enable(isp); |
@@ -1325,7 +1316,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) | |||
1325 | if (machine_is_omap_h2()) | 1316 | if (machine_is_omap_h2()) |
1326 | isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); | 1317 | isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); |
1327 | 1318 | ||
1328 | dev_info(&isp->client.dev, "A-Host sessions ok\n"); | 1319 | dev_info(&isp->client->dev, "A-Host sessions ok\n"); |
1329 | isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, | 1320 | isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, |
1330 | INTR_ID_GND); | 1321 | INTR_ID_GND); |
1331 | isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, | 1322 | isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, |
@@ -1343,7 +1334,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) | |||
1343 | return 0; | 1334 | return 0; |
1344 | 1335 | ||
1345 | #else | 1336 | #else |
1346 | dev_dbg(&isp->client.dev, "host sessions not allowed\n"); | 1337 | dev_dbg(&isp->client->dev, "host sessions not allowed\n"); |
1347 | return -EINVAL; | 1338 | return -EINVAL; |
1348 | #endif | 1339 | #endif |
1349 | 1340 | ||
@@ -1370,7 +1361,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) | |||
1370 | 1361 | ||
1371 | #ifdef CONFIG_USB_OTG | 1362 | #ifdef CONFIG_USB_OTG |
1372 | isp->otg.gadget = gadget; | 1363 | isp->otg.gadget = gadget; |
1373 | dev_dbg(&isp->client.dev, "registered gadget\n"); | 1364 | dev_dbg(&isp->client->dev, "registered gadget\n"); |
1374 | /* gadget driver may be suspended until vbus_connect () */ | 1365 | /* gadget driver may be suspended until vbus_connect () */ |
1375 | if (isp->otg.host) | 1366 | if (isp->otg.host) |
1376 | return isp1301_otg_enable(isp); | 1367 | return isp1301_otg_enable(isp); |
@@ -1395,7 +1386,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) | |||
1395 | INTR_SESS_VLD); | 1386 | INTR_SESS_VLD); |
1396 | isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, | 1387 | isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, |
1397 | INTR_VBUS_VLD); | 1388 | INTR_VBUS_VLD); |
1398 | dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); | 1389 | dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); |
1399 | dump_regs(isp, __func__); | 1390 | dump_regs(isp, __func__); |
1400 | 1391 | ||
1401 | /* If this has a Mini-AB connector, this mode is highly | 1392 | /* If this has a Mini-AB connector, this mode is highly |
@@ -1408,7 +1399,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) | |||
1408 | return 0; | 1399 | return 0; |
1409 | 1400 | ||
1410 | #else | 1401 | #else |
1411 | dev_dbg(&isp->client.dev, "peripheral sessions not allowed\n"); | 1402 | dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); |
1412 | return -EINVAL; | 1403 | return -EINVAL; |
1413 | #endif | 1404 | #endif |
1414 | } | 1405 | } |
@@ -1508,12 +1499,10 @@ isp1301_start_hnp(struct otg_transceiver *dev) | |||
1508 | 1499 | ||
1509 | /*-------------------------------------------------------------------------*/ | 1500 | /*-------------------------------------------------------------------------*/ |
1510 | 1501 | ||
1511 | /* no error returns, they'd just make bus scanning stop */ | 1502 | static int __init isp1301_probe(struct i2c_client *i2c) |
1512 | static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) | ||
1513 | { | 1503 | { |
1514 | int status; | 1504 | int status; |
1515 | struct isp1301 *isp; | 1505 | struct isp1301 *isp; |
1516 | struct i2c_client *i2c; | ||
1517 | 1506 | ||
1518 | if (the_transceiver) | 1507 | if (the_transceiver) |
1519 | return 0; | 1508 | return 0; |
@@ -1527,37 +1516,19 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) | |||
1527 | isp->timer.function = isp1301_timer; | 1516 | isp->timer.function = isp1301_timer; |
1528 | isp->timer.data = (unsigned long) isp; | 1517 | isp->timer.data = (unsigned long) isp; |
1529 | 1518 | ||
1530 | isp->irq = -1; | 1519 | i2c_set_clientdata(i2c, isp); |
1531 | isp->client.addr = address; | 1520 | isp->client = i2c; |
1532 | i2c_set_clientdata(&isp->client, isp); | ||
1533 | isp->client.adapter = bus; | ||
1534 | isp->client.driver = &isp1301_driver; | ||
1535 | strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE); | ||
1536 | i2c = &isp->client; | ||
1537 | |||
1538 | /* if this is a true probe, verify the chip ... */ | ||
1539 | if (kind < 0) { | ||
1540 | status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); | ||
1541 | if (status != I2C_VENDOR_ID_PHILIPS) { | ||
1542 | dev_dbg(&bus->dev, "addr %d not philips id: %d\n", | ||
1543 | address, status); | ||
1544 | goto fail1; | ||
1545 | } | ||
1546 | status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); | ||
1547 | if (status != I2C_PRODUCT_ID_PHILIPS_1301) { | ||
1548 | dev_dbg(&bus->dev, "%d not isp1301, %d\n", | ||
1549 | address, status); | ||
1550 | goto fail1; | ||
1551 | } | ||
1552 | } | ||
1553 | 1521 | ||
1554 | status = i2c_attach_client(i2c); | 1522 | /* verify the chip (shouldn't be necesary) */ |
1555 | if (status < 0) { | 1523 | status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); |
1556 | dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n", | 1524 | if (status != I2C_VENDOR_ID_PHILIPS) { |
1557 | DRIVER_NAME, address, status); | 1525 | dev_dbg(&i2c->dev, "not philips id: %d\n", status); |
1558 | fail1: | 1526 | goto fail; |
1559 | kfree(isp); | 1527 | } |
1560 | return 0; | 1528 | status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); |
1529 | if (status != I2C_PRODUCT_ID_PHILIPS_1301) { | ||
1530 | dev_dbg(&i2c->dev, "not isp1301, %d\n", status); | ||
1531 | goto fail; | ||
1561 | } | 1532 | } |
1562 | isp->i2c_release = i2c->dev.release; | 1533 | isp->i2c_release = i2c->dev.release; |
1563 | i2c->dev.release = isp1301_release; | 1534 | i2c->dev.release = isp1301_release; |
@@ -1586,7 +1557,7 @@ fail1: | |||
1586 | status = otg_bind(isp); | 1557 | status = otg_bind(isp); |
1587 | if (status < 0) { | 1558 | if (status < 0) { |
1588 | dev_dbg(&i2c->dev, "can't bind OTG\n"); | 1559 | dev_dbg(&i2c->dev, "can't bind OTG\n"); |
1589 | goto fail2; | 1560 | goto fail; |
1590 | } | 1561 | } |
1591 | #endif | 1562 | #endif |
1592 | 1563 | ||
@@ -1599,26 +1570,21 @@ fail1: | |||
1599 | 1570 | ||
1600 | /* IRQ wired at M14 */ | 1571 | /* IRQ wired at M14 */ |
1601 | omap_cfg_reg(M14_1510_GPIO2); | 1572 | omap_cfg_reg(M14_1510_GPIO2); |
1602 | isp->irq = OMAP_GPIO_IRQ(2); | ||
1603 | if (gpio_request(2, "isp1301") == 0) | 1573 | if (gpio_request(2, "isp1301") == 0) |
1604 | gpio_direction_input(2); | 1574 | gpio_direction_input(2); |
1605 | isp->irq_type = IRQF_TRIGGER_FALLING; | 1575 | isp->irq_type = IRQF_TRIGGER_FALLING; |
1606 | } | 1576 | } |
1607 | 1577 | ||
1608 | isp->irq_type |= IRQF_SAMPLE_RANDOM; | 1578 | isp->irq_type |= IRQF_SAMPLE_RANDOM; |
1609 | status = request_irq(isp->irq, isp1301_irq, | 1579 | status = request_irq(i2c->irq, isp1301_irq, |
1610 | isp->irq_type, DRIVER_NAME, isp); | 1580 | isp->irq_type, DRIVER_NAME, isp); |
1611 | if (status < 0) { | 1581 | if (status < 0) { |
1612 | dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", | 1582 | dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", |
1613 | isp->irq, status); | 1583 | i2c->irq, status); |
1614 | #ifdef CONFIG_USB_OTG | 1584 | goto fail; |
1615 | fail2: | ||
1616 | #endif | ||
1617 | i2c_detach_client(i2c); | ||
1618 | goto fail1; | ||
1619 | } | 1585 | } |
1620 | 1586 | ||
1621 | isp->otg.dev = &isp->client.dev; | 1587 | isp->otg.dev = &i2c->dev; |
1622 | isp->otg.label = DRIVER_NAME; | 1588 | isp->otg.label = DRIVER_NAME; |
1623 | 1589 | ||
1624 | isp->otg.set_host = isp1301_set_host, | 1590 | isp->otg.set_host = isp1301_set_host, |
@@ -1649,22 +1615,25 @@ fail2: | |||
1649 | status); | 1615 | status); |
1650 | 1616 | ||
1651 | return 0; | 1617 | return 0; |
1652 | } | ||
1653 | 1618 | ||
1654 | static int isp1301_scan_bus(struct i2c_adapter *bus) | 1619 | fail: |
1655 | { | 1620 | kfree(isp); |
1656 | if (!i2c_check_functionality(bus, I2C_FUNC_SMBUS_BYTE_DATA | 1621 | return -ENODEV; |
1657 | | I2C_FUNC_SMBUS_READ_WORD_DATA)) | ||
1658 | return -EINVAL; | ||
1659 | return i2c_probe(bus, &addr_data, isp1301_probe); | ||
1660 | } | 1622 | } |
1661 | 1623 | ||
1624 | static const struct i2c_device_id isp1301_id[] = { | ||
1625 | { "isp1301_omap", 0 }, | ||
1626 | { } | ||
1627 | }; | ||
1628 | MODULE_DEVICE_TABLE(i2c, isp1301_id); | ||
1629 | |||
1662 | static struct i2c_driver isp1301_driver = { | 1630 | static struct i2c_driver isp1301_driver = { |
1663 | .driver = { | 1631 | .driver = { |
1664 | .name = "isp1301_omap", | 1632 | .name = "isp1301_omap", |
1665 | }, | 1633 | }, |
1666 | .attach_adapter = isp1301_scan_bus, | 1634 | .probe = isp1301_probe, |
1667 | .detach_client = isp1301_detach_client, | 1635 | .remove = __exit_p(isp1301_remove), |
1636 | .id_table = isp1301_id, | ||
1668 | }; | 1637 | }; |
1669 | 1638 | ||
1670 | /*-------------------------------------------------------------------------*/ | 1639 | /*-------------------------------------------------------------------------*/ |