Lines Matching +full:pass +full:- +full:1
2 * 1-wire busmaster driver for DS1WM and ASICs with embedded DS1WMs
6 * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
7 * Copyright (c) 2004-2007, Matt Reimer <mreimer@vpop.net>
35 #define DS1WM_CLKDIV 0x04 /* R/W 5 bits of divisor and pre-scale */
38 #define DS1WM_CMD_1W_RESET (1 << 0) /* force reset on 1-wire bus */
39 #define DS1WM_CMD_SRA (1 << 1) /* enable Search ROM accelerator mode */
40 #define DS1WM_CMD_DQ_OUTPUT (1 << 2) /* write only - forces bus low */
41 #define DS1WM_CMD_DQ_INPUT (1 << 3) /* read only - reflects state of bus */
42 #define DS1WM_CMD_RST (1 << 5) /* software reset */
43 #define DS1WM_CMD_OD (1 << 7) /* overdrive */
45 #define DS1WM_INT_PD (1 << 0) /* presence detect */
46 #define DS1WM_INT_PDR (1 << 1) /* presence detect result */
47 #define DS1WM_INT_TBE (1 << 2) /* tx buffer empty */
48 #define DS1WM_INT_TSRE (1 << 3) /* tx shift register empty */
49 #define DS1WM_INT_RBF (1 << 4) /* rx buffer full */
50 #define DS1WM_INT_RSRF (1 << 5) /* rx shift register full */
52 #define DS1WM_INTEN_EPD (1 << 0) /* enable presence detect int */
53 #define DS1WM_INTEN_IAS (1 << 1) /* INTR active state */
54 #define DS1WM_INTEN_ETBE (1 << 2) /* enable tx buffer empty int */
55 #define DS1WM_INTEN_ETMT (1 << 3) /* enable tx shift register empty int */
56 #define DS1WM_INTEN_ERBF (1 << 4) /* enable rx buffer full int */
57 #define DS1WM_INTEN_ERSRF (1 << 5) /* enable rx shift register full int */
58 #define DS1WM_INTEN_DQO (1 << 6) /* enable direct bus driving ops */
92 /* you can continue this table, consult the OPERATION - CLOCK DIVISOR
119 if (ds1wm_data->is_hw_big_endian) { in ds1wm_write_register()
120 switch (ds1wm_data->bus_shift) { in ds1wm_write_register()
122 iowrite8(val, ds1wm_data->map + (reg << 0)); in ds1wm_write_register()
124 case 1: in ds1wm_write_register()
125 iowrite16be((u16)val, ds1wm_data->map + (reg << 1)); in ds1wm_write_register()
128 iowrite32be((u32)val, ds1wm_data->map + (reg << 2)); in ds1wm_write_register()
132 switch (ds1wm_data->bus_shift) { in ds1wm_write_register()
134 iowrite8(val, ds1wm_data->map + (reg << 0)); in ds1wm_write_register()
136 case 1: in ds1wm_write_register()
137 iowrite16((u16)val, ds1wm_data->map + (reg << 1)); in ds1wm_write_register()
140 iowrite32((u32)val, ds1wm_data->map + (reg << 2)); in ds1wm_write_register()
150 if (ds1wm_data->is_hw_big_endian) { in ds1wm_read_register()
151 switch (ds1wm_data->bus_shift) { in ds1wm_read_register()
153 val = ioread8(ds1wm_data->map + (reg << 0)); in ds1wm_read_register()
155 case 1: in ds1wm_read_register()
156 val = ioread16be(ds1wm_data->map + (reg << 1)); in ds1wm_read_register()
159 val = ioread32be(ds1wm_data->map + (reg << 2)); in ds1wm_read_register()
163 switch (ds1wm_data->bus_shift) { in ds1wm_read_register()
165 val = ioread8(ds1wm_data->map + (reg << 0)); in ds1wm_read_register()
167 case 1: in ds1wm_read_register()
168 val = ioread16(ds1wm_data->map + (reg << 1)); in ds1wm_read_register()
171 val = ioread32(ds1wm_data->map + (reg << 2)); in ds1wm_read_register()
175 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_read_register()
192 DS1WM_INT_EN, ds1wm_data->int_en_reg_none); in ds1wm_isr()
197 ds1wm_data->slave_present = (intr & DS1WM_INT_PDR) ? 0 : 1; in ds1wm_isr()
199 if ((intr & DS1WM_INT_TSRE) && ds1wm_data->write_complete) { in ds1wm_isr()
201 complete(ds1wm_data->write_complete); in ds1wm_isr()
205 ds1wm_data->read_byte = ds1wm_read_register(ds1wm_data, in ds1wm_isr()
208 if (ds1wm_data->read_complete) in ds1wm_isr()
209 complete(ds1wm_data->read_complete); in ds1wm_isr()
211 if ((intr & DS1WM_INT_PD) && ds1wm_data->reset_complete) { in ds1wm_isr()
213 complete(ds1wm_data->reset_complete); in ds1wm_isr()
225 ds1wm_data->reset_complete = &reset_done; in ds1wm_reset()
229 ds1wm_data->int_en_reg_none); in ds1wm_reset()
234 ds1wm_data->reset_complete = NULL; in ds1wm_reset()
236 dev_err(&ds1wm_data->pdev->dev, "reset failed, timed out\n"); in ds1wm_reset()
237 return 1; in ds1wm_reset()
240 if (!ds1wm_data->slave_present) { in ds1wm_reset()
241 dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n"); in ds1wm_reset()
242 return 1; in ds1wm_reset()
245 if (ds1wm_data->reset_recover_delay) in ds1wm_reset()
246 msleep(ds1wm_data->reset_recover_delay); in ds1wm_reset()
255 ds1wm_data->write_complete = &write_done; in ds1wm_write()
258 ds1wm_data->int_en_reg_none | DS1WM_INTEN_ETMT); in ds1wm_write()
264 ds1wm_data->write_complete = NULL; in ds1wm_write()
266 dev_err(&ds1wm_data->pdev->dev, "write failed, timed out\n"); in ds1wm_write()
267 return -ETIMEDOUT; in ds1wm_write()
276 u8 intEnable = DS1WM_INTEN_ERBF | ds1wm_data->int_en_reg_none; in ds1wm_read()
281 ds1wm_data->read_complete = &read_done; in ds1wm_read()
287 ds1wm_data->read_complete = NULL; in ds1wm_read()
289 dev_err(&ds1wm_data->pdev->dev, "read failed, timed out\n"); in ds1wm_read()
290 ds1wm_data->read_error = -ETIMEDOUT; in ds1wm_read()
293 ds1wm_data->read_error = 0; in ds1wm_read()
294 return ds1wm_data->read_byte; in ds1wm_read()
301 for (i = ARRAY_SIZE(freq)-1; i >= 0; --i) in ds1wm_find_divisor()
311 struct device *dev = &ds1wm_data->pdev->dev; in ds1wm_up()
314 if (ds1wm_data->cell->enable) in ds1wm_up()
315 ds1wm_data->cell->enable(ds1wm_data->pdev); in ds1wm_up()
317 divisor = ds1wm_find_divisor(plat->clock_rate); in ds1wm_up()
319 divisor, plat->clock_rate); in ds1wm_up()
322 plat->clock_rate); in ds1wm_up()
328 msleep(1); in ds1wm_up()
339 ds1wm_data->int_en_reg_none); in ds1wm_down()
341 if (ds1wm_data->cell->disable) in ds1wm_down()
342 ds1wm_data->cell->disable(ds1wm_data->pdev); in ds1wm_down()
345 /* --------------------------------------------------------------------- */
376 int ms_discrep_bit = -1; in ds1wm_search()
380 unsigned int pass = 0; in ds1wm_search() local
382 dev_dbg(&ds1wm_data->pdev->dev, "search begin\n"); in ds1wm_search()
384 ++pass; in ds1wm_search()
385 if (pass > 100) { in ds1wm_search()
386 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
391 mutex_lock(&master_dev->bus_mutex); in ds1wm_search()
393 mutex_unlock(&master_dev->bus_mutex); in ds1wm_search()
394 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
395 "pass: %d reset error (or no slaves)\n", pass); in ds1wm_search()
399 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
400 "pass: %d r : %0#18llx writing SEARCH_ROM\n", pass, r); in ds1wm_search()
402 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
403 "pass: %d entering ASM\n", pass); in ds1wm_search()
405 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
406 "pass: %d beginning nibble loop\n", pass); in ds1wm_search()
417 _r = ((_r & 0x1) << 1) | in ds1wm_search()
425 if (ds1wm_data->read_error) { in ds1wm_search()
426 dev_err(&ds1wm_data->pdev->dev, in ds1wm_search()
427 "pass: %d nibble: %d read error\n", pass, i); in ds1wm_search()
431 _r_prime = ((resp & 0x02) >> 1) | in ds1wm_search()
437 ((resp & 0x04) >> 1) | in ds1wm_search()
445 if (ds1wm_data->read_error) { in ds1wm_search()
446 mutex_unlock(&master_dev->bus_mutex); in ds1wm_search()
447 dev_err(&ds1wm_data->pdev->dev, in ds1wm_search()
448 "pass: %d read error, retrying\n", pass); in ds1wm_search()
451 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
452 "pass: %d r\': %0#18llx d:%0#18llx\n", in ds1wm_search()
453 pass, r_prime, d); in ds1wm_search()
454 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
455 "pass: %d nibble loop complete, exiting ASM\n", pass); in ds1wm_search()
457 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
458 "pass: %d resetting bus\n", pass); in ds1wm_search()
460 mutex_unlock(&master_dev->bus_mutex); in ds1wm_search()
461 if ((r_prime & ((u64)1 << 63)) && (d & ((u64)1 << 63))) { in ds1wm_search()
462 dev_err(&ds1wm_data->pdev->dev, in ds1wm_search()
463 "pass: %d bus error, retrying\n", pass); in ds1wm_search()
468 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
469 "pass: %d found %0#18llx\n", pass, r_prime); in ds1wm_search()
472 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
473 "pass: %d complete, preparing next pass\n", pass); in ds1wm_search()
476 '1' branch is now is now irrelevant we reveal the in ds1wm_search()
480 ms_discrep_bit = fls64(d) - 1; in ds1wm_search()
481 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
482 "pass: %d new d:%0#18llx MS discrep bit:%d\n", in ds1wm_search()
483 pass, d, ms_discrep_bit); in ds1wm_search()
487 if (ms_discrep_bit == -1) in ds1wm_search()
490 r = (r & ~(~0ull << (ms_discrep_bit))) | 1 << ms_discrep_bit; in ds1wm_search()
492 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_search()
493 "pass: %d total: %d search done ms d bit pos: %d\n", pass, in ds1wm_search()
497 /* --------------------------------------------------------------------- */
515 return -ENODEV; in ds1wm_probe()
517 ds1wm_data = devm_kzalloc(&pdev->dev, sizeof(*ds1wm_data), GFP_KERNEL); in ds1wm_probe()
519 return -ENOMEM; in ds1wm_probe()
525 return -ENXIO; in ds1wm_probe()
526 ds1wm_data->map = devm_ioremap(&pdev->dev, res->start, in ds1wm_probe()
528 if (!ds1wm_data->map) in ds1wm_probe()
529 return -ENOMEM; in ds1wm_probe()
531 ds1wm_data->pdev = pdev; in ds1wm_probe()
532 ds1wm_data->cell = mfd_get_cell(pdev); in ds1wm_probe()
533 if (!ds1wm_data->cell) in ds1wm_probe()
534 return -ENODEV; in ds1wm_probe()
535 plat = dev_get_platdata(&pdev->dev); in ds1wm_probe()
537 return -ENODEV; in ds1wm_probe()
540 if (plat->bus_shift > 2) { in ds1wm_probe()
541 dev_err(&ds1wm_data->pdev->dev, in ds1wm_probe()
543 ds1wm_data->bus_shift); in ds1wm_probe()
544 return -EINVAL; in ds1wm_probe()
547 ds1wm_data->bus_shift = plat->bus_shift; in ds1wm_probe()
549 if ((8 << ds1wm_data->bus_shift) > resource_size(res)) { in ds1wm_probe()
550 dev_err(&ds1wm_data->pdev->dev, in ds1wm_probe()
553 8 << ds1wm_data->bus_shift); in ds1wm_probe()
554 return -EINVAL; in ds1wm_probe()
557 ds1wm_data->is_hw_big_endian = plat->is_hw_big_endian; in ds1wm_probe()
561 return -ENXIO; in ds1wm_probe()
562 ds1wm_data->irq = res->start; in ds1wm_probe()
563 ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0); in ds1wm_probe()
564 ds1wm_data->reset_recover_delay = plat->reset_recover_delay; in ds1wm_probe()
569 DS1WM_INT_EN, ds1wm_data->int_en_reg_none); in ds1wm_probe()
571 if (res->flags & IORESOURCE_IRQ_HIGHEDGE) in ds1wm_probe()
572 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING); in ds1wm_probe()
573 if (res->flags & IORESOURCE_IRQ_LOWEDGE) in ds1wm_probe()
574 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING); in ds1wm_probe()
575 if (res->flags & IORESOURCE_IRQ_HIGHLEVEL) in ds1wm_probe()
576 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_HIGH); in ds1wm_probe()
577 if (res->flags & IORESOURCE_IRQ_LOWLEVEL) in ds1wm_probe()
578 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_LOW); in ds1wm_probe()
580 ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr, in ds1wm_probe()
583 dev_err(&ds1wm_data->pdev->dev, in ds1wm_probe()
585 ds1wm_data->irq, in ds1wm_probe()
599 dev_dbg(&ds1wm_data->pdev->dev, in ds1wm_probe()
600 …"ds1wm: probe successful, IAS: %d, rec.delay: %d, clockrate: %d, bus-shift: %d, is Hw Big Endian: … in ds1wm_probe()
601 plat->active_high, in ds1wm_probe()
602 plat->reset_recover_delay, in ds1wm_probe()
603 plat->clock_rate, in ds1wm_probe()
604 ds1wm_data->bus_shift, in ds1wm_probe()
605 ds1wm_data->is_hw_big_endian); in ds1wm_probe()
659 pr_info("DS1WM w1 busmaster driver - (c) 2004 Szabolcs Gyurko\n"); in ds1wm_init()
674 "Jean-Francois Dagenais <dagenaisj@sonatest.com>");