aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 16:57:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 16:57:13 -0500
commit7ed214ac2095f561a94335ca672b6c42a1ea40ff (patch)
treeda41901bff1d0d8d61170bf362384fdc61deb3ab /drivers/w1
parent21eaab6d19ed43e82ed39c8deb7f192134fb4a0e (diff)
parent29e5507ae4ab34397f538f06b7070c81a4e4a2bf (diff)
Merge tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver patches from Greg Kroah-Hartman: "Here's the big char/misc driver patches for 3.9-rc1. Nothing major here, just lots of different driver updates (mei, hyperv, ipack, extcon, vmci, etc.). All of these have been in the linux-next tree for a while." * tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (209 commits) w1: w1_therm: Add force-pullup option for "broken" sensors w1: ds2482: Added 1-Wire pull-up support to the driver vme: add missing put_device() after device_register() fails extcon: max8997: Use workqueue to check cable state after completing boot of platform extcon: max8997: Set default UART/USB path on probe extcon: max8997: Consolidate duplicate code for checking ADC/CHG cable type extcon: max8997: Set default of ADC debounce time during initialization extcon: max8997: Remove duplicate code related to set H/W line path extcon: max8997: Move defined constant to header file extcon: max77693: Make max77693_extcon_cable static extcon: max8997: Remove unreachable code extcon: max8997: Make max8997_extcon_cable static extcon: max77693: Remove unnecessary goto statement to improve readability extcon: max77693: Convert to devm_input_allocate_device() extcon: gpio: Rename filename of extcon-gpio.c according to kernel naming style CREDITS: update email and address of Harald Hoyer extcon: arizona: Use MICDET for final microphone identification extcon: arizona: Always take the first HPDET reading as the final one extcon: arizona: Clear _trig_sts bits after jack detection extcon: arizona: Don't HPDET magic when headphones are enabled ...
Diffstat (limited to 'drivers/w1')
-rw-r--r--drivers/w1/masters/ds1wm.c52
-rw-r--r--drivers/w1/masters/ds2482.c51
-rw-r--r--drivers/w1/masters/mxc_w1.c49
-rw-r--r--drivers/w1/masters/w1-gpio.c2
-rw-r--r--drivers/w1/slaves/w1_therm.c36
5 files changed, 90 insertions, 100 deletions
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 7c294f4dc0ed..96cab6ac2b4e 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/io.h>
16#include <linux/irq.h> 17#include <linux/irq.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
@@ -459,43 +460,34 @@ static int ds1wm_probe(struct platform_device *pdev)
459 if (!pdev) 460 if (!pdev)
460 return -ENODEV; 461 return -ENODEV;
461 462
462 ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL); 463 ds1wm_data = devm_kzalloc(&pdev->dev, sizeof(*ds1wm_data), GFP_KERNEL);
463 if (!ds1wm_data) 464 if (!ds1wm_data)
464 return -ENOMEM; 465 return -ENOMEM;
465 466
466 platform_set_drvdata(pdev, ds1wm_data); 467 platform_set_drvdata(pdev, ds1wm_data);
467 468
468 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 469 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
469 if (!res) { 470 if (!res)
470 ret = -ENXIO; 471 return -ENXIO;
471 goto err0; 472 ds1wm_data->map = devm_ioremap(&pdev->dev, res->start,
472 } 473 resource_size(res));
473 ds1wm_data->map = ioremap(res->start, resource_size(res)); 474 if (!ds1wm_data->map)
474 if (!ds1wm_data->map) { 475 return -ENOMEM;
475 ret = -ENOMEM;
476 goto err0;
477 }
478 476
479 /* calculate bus shift from mem resource */ 477 /* calculate bus shift from mem resource */
480 ds1wm_data->bus_shift = resource_size(res) >> 3; 478 ds1wm_data->bus_shift = resource_size(res) >> 3;
481 479
482 ds1wm_data->pdev = pdev; 480 ds1wm_data->pdev = pdev;
483 ds1wm_data->cell = mfd_get_cell(pdev); 481 ds1wm_data->cell = mfd_get_cell(pdev);
484 if (!ds1wm_data->cell) { 482 if (!ds1wm_data->cell)
485 ret = -ENODEV; 483 return -ENODEV;
486 goto err1;
487 }
488 plat = pdev->dev.platform_data; 484 plat = pdev->dev.platform_data;
489 if (!plat) { 485 if (!plat)
490 ret = -ENODEV; 486 return -ENODEV;
491 goto err1;
492 }
493 487
494 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 488 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
495 if (!res) { 489 if (!res)
496 ret = -ENXIO; 490 return -ENXIO;
497 goto err1;
498 }
499 ds1wm_data->irq = res->start; 491 ds1wm_data->irq = res->start;
500 ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0); 492 ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0);
501 ds1wm_data->reset_recover_delay = plat->reset_recover_delay; 493 ds1wm_data->reset_recover_delay = plat->reset_recover_delay;
@@ -505,10 +497,10 @@ static int ds1wm_probe(struct platform_device *pdev)
505 if (res->flags & IORESOURCE_IRQ_LOWEDGE) 497 if (res->flags & IORESOURCE_IRQ_LOWEDGE)
506 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING); 498 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
507 499
508 ret = request_irq(ds1wm_data->irq, ds1wm_isr, 500 ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr,
509 IRQF_DISABLED | IRQF_SHARED, "ds1wm", ds1wm_data); 501 IRQF_DISABLED | IRQF_SHARED, "ds1wm", ds1wm_data);
510 if (ret) 502 if (ret)
511 goto err1; 503 return ret;
512 504
513 ds1wm_up(ds1wm_data); 505 ds1wm_up(ds1wm_data);
514 506
@@ -516,17 +508,12 @@ static int ds1wm_probe(struct platform_device *pdev)
516 508
517 ret = w1_add_master_device(&ds1wm_master); 509 ret = w1_add_master_device(&ds1wm_master);
518 if (ret) 510 if (ret)
519 goto err2; 511 goto err;
520 512
521 return 0; 513 return 0;
522 514
523err2: 515err:
524 ds1wm_down(ds1wm_data); 516 ds1wm_down(ds1wm_data);
525 free_irq(ds1wm_data->irq, ds1wm_data);
526err1:
527 iounmap(ds1wm_data->map);
528err0:
529 kfree(ds1wm_data);
530 517
531 return ret; 518 return ret;
532} 519}
@@ -560,9 +547,6 @@ static int ds1wm_remove(struct platform_device *pdev)
560 547
561 w1_remove_master_device(&ds1wm_master); 548 w1_remove_master_device(&ds1wm_master);
562 ds1wm_down(ds1wm_data); 549 ds1wm_down(ds1wm_data);
563 free_irq(ds1wm_data->irq, ds1wm_data);
564 iounmap(ds1wm_data->map);
565 kfree(ds1wm_data);
566 550
567 return 0; 551 return 0;
568} 552}
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
index 6429b9e9fb82..e033491fe308 100644
--- a/drivers/w1/masters/ds2482.c
+++ b/drivers/w1/masters/ds2482.c
@@ -51,10 +51,10 @@
51 * The top 4 bits always read 0. 51 * The top 4 bits always read 0.
52 * To write, the top nibble must be the 1's compl. of the low nibble. 52 * To write, the top nibble must be the 1's compl. of the low nibble.
53 */ 53 */
54#define DS2482_REG_CFG_1WS 0x08 54#define DS2482_REG_CFG_1WS 0x08 /* 1-wire speed */
55#define DS2482_REG_CFG_SPU 0x04 55#define DS2482_REG_CFG_SPU 0x04 /* strong pull-up */
56#define DS2482_REG_CFG_PPM 0x02 56#define DS2482_REG_CFG_PPM 0x02 /* presence pulse masking */
57#define DS2482_REG_CFG_APU 0x01 57#define DS2482_REG_CFG_APU 0x01 /* active pull-up */
58 58
59 59
60/** 60/**
@@ -132,6 +132,17 @@ struct ds2482_data {
132 132
133 133
134/** 134/**
135 * Helper to calculate values for configuration register
136 * @param conf the raw config value
137 * @return the value w/ complements that can be written to register
138 */
139static inline u8 ds2482_calculate_config(u8 conf)
140{
141 return conf | ((~conf & 0x0f) << 4);
142}
143
144
145/**
135 * Sets the read pointer. 146 * Sets the read pointer.
136 * @param pdev The ds2482 client pointer 147 * @param pdev The ds2482 client pointer
137 * @param read_ptr see DS2482_PTR_CODE_xxx above 148 * @param read_ptr see DS2482_PTR_CODE_xxx above
@@ -399,7 +410,7 @@ static u8 ds2482_w1_reset_bus(void *data)
399 /* If the chip did reset since detect, re-config it */ 410 /* If the chip did reset since detect, re-config it */
400 if (err & DS2482_REG_STS_RST) 411 if (err & DS2482_REG_STS_RST)
401 ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, 412 ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
402 0xF0); 413 ds2482_calculate_config(0x00));
403 } 414 }
404 415
405 mutex_unlock(&pdev->access_lock); 416 mutex_unlock(&pdev->access_lock);
@@ -407,6 +418,32 @@ static u8 ds2482_w1_reset_bus(void *data)
407 return retval; 418 return retval;
408} 419}
409 420
421static u8 ds2482_w1_set_pullup(void *data, int delay)
422{
423 struct ds2482_w1_chan *pchan = data;
424 struct ds2482_data *pdev = pchan->pdev;
425 u8 retval = 1;
426
427 /* if delay is non-zero activate the pullup,
428 * the strong pullup will be automatically deactivated
429 * by the master, so do not explicitly deactive it
430 */
431 if (delay) {
432 /* both waits are crucial, otherwise devices might not be
433 * powered long enough, causing e.g. a w1_therm sensor to
434 * provide wrong conversion results
435 */
436 ds2482_wait_1wire_idle(pdev);
437 /* note: it seems like both SPU and APU have to be set! */
438 retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
439 ds2482_calculate_config(DS2482_REG_CFG_SPU |
440 DS2482_REG_CFG_APU));
441 ds2482_wait_1wire_idle(pdev);
442 }
443
444 return retval;
445}
446
410 447
411static int ds2482_probe(struct i2c_client *client, 448static int ds2482_probe(struct i2c_client *client,
412 const struct i2c_device_id *id) 449 const struct i2c_device_id *id)
@@ -452,7 +489,8 @@ static int ds2482_probe(struct i2c_client *client,
452 data->w1_count = 8; 489 data->w1_count = 8;
453 490
454 /* Set all config items to 0 (off) */ 491 /* Set all config items to 0 (off) */
455 ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0); 492 ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG,
493 ds2482_calculate_config(0x00));
456 494
457 mutex_init(&data->access_lock); 495 mutex_init(&data->access_lock);
458 496
@@ -468,6 +506,7 @@ static int ds2482_probe(struct i2c_client *client,
468 data->w1_ch[idx].w1_bm.touch_bit = ds2482_w1_touch_bit; 506 data->w1_ch[idx].w1_bm.touch_bit = ds2482_w1_touch_bit;
469 data->w1_ch[idx].w1_bm.triplet = ds2482_w1_triplet; 507 data->w1_ch[idx].w1_bm.triplet = ds2482_w1_triplet;
470 data->w1_ch[idx].w1_bm.reset_bus = ds2482_w1_reset_bus; 508 data->w1_ch[idx].w1_bm.reset_bus = ds2482_w1_reset_bus;
509 data->w1_ch[idx].w1_bm.set_pullup = ds2482_w1_set_pullup;
471 510
472 err = w1_add_master_device(&data->w1_ch[idx].w1_bm); 511 err = w1_add_master_device(&data->w1_ch[idx].w1_bm);
473 if (err) { 512 if (err) {
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index 708a25fc9961..372c8c0d54a0 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -109,34 +109,21 @@ static int mxc_w1_probe(struct platform_device *pdev)
109 struct resource *res; 109 struct resource *res;
110 int err = 0; 110 int err = 0;
111 111
112 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 112 mdev = devm_kzalloc(&pdev->dev, sizeof(struct mxc_w1_device),
113 if (!res) 113 GFP_KERNEL);
114 return -ENODEV;
115
116 mdev = kzalloc(sizeof(struct mxc_w1_device), GFP_KERNEL);
117 if (!mdev) 114 if (!mdev)
118 return -ENOMEM; 115 return -ENOMEM;
119 116
120 mdev->clk = clk_get(&pdev->dev, NULL); 117 mdev->clk = devm_clk_get(&pdev->dev, NULL);
121 if (IS_ERR(mdev->clk)) { 118 if (IS_ERR(mdev->clk))
122 err = PTR_ERR(mdev->clk); 119 return PTR_ERR(mdev->clk);
123 goto failed_clk;
124 }
125 120
126 mdev->clkdiv = (clk_get_rate(mdev->clk) / 1000000) - 1; 121 mdev->clkdiv = (clk_get_rate(mdev->clk) / 1000000) - 1;
127 122
128 res = request_mem_region(res->start, resource_size(res), 123 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
129 "mxc_w1"); 124 mdev->regs = devm_request_and_ioremap(&pdev->dev, res);
130 if (!res) { 125 if (!mdev->regs)
131 err = -EBUSY; 126 return -EBUSY;
132 goto failed_req;
133 }
134
135 mdev->regs = ioremap(res->start, resource_size(res));
136 if (!mdev->regs) {
137 dev_err(&pdev->dev, "Cannot map mxc_w1 registers\n");
138 goto failed_ioremap;
139 }
140 127
141 clk_prepare_enable(mdev->clk); 128 clk_prepare_enable(mdev->clk);
142 __raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER); 129 __raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER);
@@ -148,20 +135,10 @@ static int mxc_w1_probe(struct platform_device *pdev)
148 err = w1_add_master_device(&mdev->bus_master); 135 err = w1_add_master_device(&mdev->bus_master);
149 136
150 if (err) 137 if (err)
151 goto failed_add; 138 return err;
152 139
153 platform_set_drvdata(pdev, mdev); 140 platform_set_drvdata(pdev, mdev);
154 return 0; 141 return 0;
155
156failed_add:
157 iounmap(mdev->regs);
158failed_ioremap:
159 release_mem_region(res->start, resource_size(res));
160failed_req:
161 clk_put(mdev->clk);
162failed_clk:
163 kfree(mdev);
164 return err;
165} 142}
166 143
167/* 144/*
@@ -170,16 +147,10 @@ failed_clk:
170static int mxc_w1_remove(struct platform_device *pdev) 147static int mxc_w1_remove(struct platform_device *pdev)
171{ 148{
172 struct mxc_w1_device *mdev = platform_get_drvdata(pdev); 149 struct mxc_w1_device *mdev = platform_get_drvdata(pdev);
173 struct resource *res;
174
175 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
176 150
177 w1_remove_master_device(&mdev->bus_master); 151 w1_remove_master_device(&mdev->bus_master);
178 152
179 iounmap(mdev->regs);
180 release_mem_region(res->start, resource_size(res));
181 clk_disable_unprepare(mdev->clk); 153 clk_disable_unprepare(mdev->clk);
182 clk_put(mdev->clk);
183 154
184 platform_set_drvdata(pdev, NULL); 155 platform_set_drvdata(pdev, NULL);
185 156
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 85b363a5bd0f..d39dfa4cc235 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -72,7 +72,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
72 return 0; 72 return 0;
73} 73}
74 74
75static int __init w1_gpio_probe(struct platform_device *pdev) 75static int w1_gpio_probe(struct platform_device *pdev)
76{ 76{
77 struct w1_bus_master *master; 77 struct w1_bus_master *master;
78 struct w1_gpio_platform_data *pdata; 78 struct w1_gpio_platform_data *pdata;
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 92d08e7fcba2..c1a702f8c803 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -41,14 +41,18 @@ MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature famil
41 * If it was disabled a parasite powered device might not get the require 41 * If it was disabled a parasite powered device might not get the require
42 * current to do a temperature conversion. If it is enabled parasite powered 42 * current to do a temperature conversion. If it is enabled parasite powered
43 * devices have a better chance of getting the current required. 43 * devices have a better chance of getting the current required.
44 * In case the parasite power-detection is not working (seems to be the case
45 * for some DS18S20) the strong pullup can also be forced, regardless of the
46 * power state of the devices.
47 *
48 * Summary of options:
49 * - strong_pullup = 0 Disable strong pullup completely
50 * - strong_pullup = 1 Enable automatic strong pullup detection
51 * - strong_pullup = 2 Force strong pullup
44 */ 52 */
45static int w1_strong_pullup = 1; 53static int w1_strong_pullup = 1;
46module_param_named(strong_pullup, w1_strong_pullup, int, 0); 54module_param_named(strong_pullup, w1_strong_pullup, int, 0);
47 55
48static u8 bad_roms[][9] = {
49 {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
50 {}
51 };
52 56
53static ssize_t w1_therm_read(struct device *device, 57static ssize_t w1_therm_read(struct device *device,
54 struct device_attribute *attr, char *buf); 58 struct device_attribute *attr, char *buf);
@@ -168,16 +172,6 @@ static inline int w1_convert_temp(u8 rom[9], u8 fid)
168 return 0; 172 return 0;
169} 173}
170 174
171static int w1_therm_check_rom(u8 rom[9])
172{
173 int i;
174
175 for (i=0; i<sizeof(bad_roms)/9; ++i)
176 if (!memcmp(bad_roms[i], rom, 9))
177 return 1;
178
179 return 0;
180}
181 175
182static ssize_t w1_therm_read(struct device *device, 176static ssize_t w1_therm_read(struct device *device,
183 struct device_attribute *attr, char *buf) 177 struct device_attribute *attr, char *buf)
@@ -194,10 +188,11 @@ static ssize_t w1_therm_read(struct device *device,
194 188
195 memset(rom, 0, sizeof(rom)); 189 memset(rom, 0, sizeof(rom));
196 190
197 verdict = 0;
198 crc = 0;
199
200 while (max_trying--) { 191 while (max_trying--) {
192
193 verdict = 0;
194 crc = 0;
195
201 if (!w1_reset_select_slave(sl)) { 196 if (!w1_reset_select_slave(sl)) {
202 int count = 0; 197 int count = 0;
203 unsigned int tm = 750; 198 unsigned int tm = 750;
@@ -210,7 +205,8 @@ static ssize_t w1_therm_read(struct device *device,
210 continue; 205 continue;
211 206
212 /* 750ms strong pullup (or delay) after the convert */ 207 /* 750ms strong pullup (or delay) after the convert */
213 if (!external_power && w1_strong_pullup) 208 if (w1_strong_pullup == 2 ||
209 (!external_power && w1_strong_pullup))
214 w1_next_pullup(dev, tm); 210 w1_next_pullup(dev, tm);
215 211
216 w1_write_8(dev, W1_CONVERT_TEMP); 212 w1_write_8(dev, W1_CONVERT_TEMP);
@@ -249,7 +245,7 @@ static ssize_t w1_therm_read(struct device *device,
249 } 245 }
250 } 246 }
251 247
252 if (!w1_therm_check_rom(rom)) 248 if (verdict)
253 break; 249 break;
254 } 250 }
255 251
@@ -260,7 +256,7 @@ static ssize_t w1_therm_read(struct device *device,
260 if (verdict) 256 if (verdict)
261 memcpy(sl->rom, rom, sizeof(sl->rom)); 257 memcpy(sl->rom, rom, sizeof(sl->rom));
262 else 258 else
263 dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n"); 259 dev_warn(device, "Read failed CRC check\n");
264 260
265 for (i = 0; i < 9; ++i) 261 for (i = 0; i < 9; ++i)
266 c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]); 262 c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);