diff options
Diffstat (limited to 'drivers/regulator/88pm8607.c')
-rw-r--r-- | drivers/regulator/88pm8607.c | 318 |
1 files changed, 90 insertions, 228 deletions
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 04719551381b..5fb83e2ced25 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
@@ -11,15 +11,17 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/i2c.h> | ||
14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
15 | #include <linux/regulator/driver.h> | 16 | #include <linux/regulator/driver.h> |
16 | #include <linux/regulator/machine.h> | 17 | #include <linux/regulator/machine.h> |
17 | #include <linux/mfd/88pm8607.h> | 18 | #include <linux/mfd/88pm860x.h> |
18 | 19 | ||
19 | struct pm8607_regulator_info { | 20 | struct pm8607_regulator_info { |
20 | struct regulator_desc desc; | 21 | struct regulator_desc desc; |
21 | struct pm8607_chip *chip; | 22 | struct pm860x_chip *chip; |
22 | struct regulator_dev *regulator; | 23 | struct regulator_dev *regulator; |
24 | struct i2c_client *i2c; | ||
23 | 25 | ||
24 | int min_uV; | 26 | int min_uV; |
25 | int max_uV; | 27 | int max_uV; |
@@ -46,7 +48,6 @@ static inline int check_range(struct pm8607_regulator_info *info, | |||
46 | static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) | 48 | static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) |
47 | { | 49 | { |
48 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 50 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
49 | uint8_t chip_id = info->chip->chip_id; | ||
50 | int ret = -EINVAL; | 51 | int ret = -EINVAL; |
51 | 52 | ||
52 | switch (info->desc.id) { | 53 | switch (info->desc.id) { |
@@ -88,79 +89,29 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
88 | case PM8607_ID_LDO2: | 89 | case PM8607_ID_LDO2: |
89 | case PM8607_ID_LDO3: | 90 | case PM8607_ID_LDO3: |
90 | case PM8607_ID_LDO9: | 91 | case PM8607_ID_LDO9: |
91 | switch (chip_id) { | 92 | ret = (index < 3) ? (index * 50000 + 1800000) : |
92 | case PM8607_CHIP_A0: | 93 | ((index < 7) ? (index * 50000 + 2550000) : |
93 | case PM8607_CHIP_A1: | 94 | 3300000); |
94 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
95 | ((index < 8) ? (index * 50000 + 2550000) : | ||
96 | -EINVAL); | ||
97 | break; | ||
98 | case PM8607_CHIP_B0: | ||
99 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
100 | ((index < 7) ? (index * 50000 + 2550000) : | ||
101 | 3300000); | ||
102 | break; | ||
103 | } | ||
104 | break; | 95 | break; |
105 | case PM8607_ID_LDO4: | 96 | case PM8607_ID_LDO4: |
106 | switch (chip_id) { | 97 | ret = (index < 3) ? (index * 50000 + 1800000) : |
107 | case PM8607_CHIP_A0: | 98 | ((index < 6) ? (index * 50000 + 2550000) : |
108 | case PM8607_CHIP_A1: | 99 | ((index == 6) ? 2900000 : 3300000)); |
109 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
110 | ((index < 8) ? (index * 50000 + 2550000) : | ||
111 | -EINVAL); | ||
112 | break; | ||
113 | case PM8607_CHIP_B0: | ||
114 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
115 | ((index < 6) ? (index * 50000 + 2550000) : | ||
116 | ((index == 6) ? 2900000 : 3300000)); | ||
117 | break; | ||
118 | } | ||
119 | break; | 100 | break; |
120 | case PM8607_ID_LDO6: | 101 | case PM8607_ID_LDO6: |
121 | switch (chip_id) { | 102 | ret = (index < 2) ? (index * 50000 + 1800000) : |
122 | case PM8607_CHIP_A0: | 103 | ((index < 7) ? (index * 50000 + 2500000) : |
123 | case PM8607_CHIP_A1: | 104 | 3300000); |
124 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
125 | ((index < 8) ? (index * 50000 + 2450000) : | ||
126 | -EINVAL); | ||
127 | break; | ||
128 | case PM8607_CHIP_B0: | ||
129 | ret = (index < 2) ? (index * 50000 + 1800000) : | ||
130 | ((index < 7) ? (index * 50000 + 2500000) : | ||
131 | 3300000); | ||
132 | break; | ||
133 | } | ||
134 | break; | 105 | break; |
135 | case PM8607_ID_LDO10: | 106 | case PM8607_ID_LDO10: |
136 | switch (chip_id) { | 107 | ret = (index < 3) ? (index * 50000 + 1800000) : |
137 | case PM8607_CHIP_A0: | 108 | ((index < 7) ? (index * 50000 + 2550000) : |
138 | case PM8607_CHIP_A1: | 109 | ((index == 7) ? 3300000 : 1200000)); |
139 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
140 | ((index < 8) ? (index * 50000 + 2550000) : | ||
141 | 1200000); | ||
142 | break; | ||
143 | case PM8607_CHIP_B0: | ||
144 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
145 | ((index < 7) ? (index * 50000 + 2550000) : | ||
146 | ((index == 7) ? 3300000 : 1200000)); | ||
147 | break; | ||
148 | } | ||
149 | break; | 110 | break; |
150 | case PM8607_ID_LDO14: | 111 | case PM8607_ID_LDO14: |
151 | switch (chip_id) { | 112 | ret = (index < 2) ? (index * 50000 + 1800000) : |
152 | case PM8607_CHIP_A0: | 113 | ((index < 7) ? (index * 50000 + 2600000) : |
153 | case PM8607_CHIP_A1: | 114 | 3300000); |
154 | ret = (index < 3) ? (index * 50000 + 1800000) : | ||
155 | ((index < 8) ? (index * 50000 + 2550000) : | ||
156 | -EINVAL); | ||
157 | break; | ||
158 | case PM8607_CHIP_B0: | ||
159 | ret = (index < 2) ? (index * 50000 + 1800000) : | ||
160 | ((index < 7) ? (index * 50000 + 2600000) : | ||
161 | 3300000); | ||
162 | break; | ||
163 | } | ||
164 | break; | 115 | break; |
165 | } | 116 | } |
166 | return ret; | 117 | return ret; |
@@ -169,7 +120,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
169 | static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | 120 | static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) |
170 | { | 121 | { |
171 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 122 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
172 | uint8_t chip_id = info->chip->chip_id; | ||
173 | int val = -ENOENT; | 123 | int val = -ENOENT; |
174 | int ret; | 124 | int ret; |
175 | 125 | ||
@@ -254,161 +204,77 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
254 | case PM8607_ID_LDO2: | 204 | case PM8607_ID_LDO2: |
255 | case PM8607_ID_LDO3: | 205 | case PM8607_ID_LDO3: |
256 | case PM8607_ID_LDO9: | 206 | case PM8607_ID_LDO9: |
257 | switch (chip_id) { | 207 | if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ |
258 | case PM8607_CHIP_A0: | 208 | if (min_uV <= 1800000) |
259 | case PM8607_CHIP_A1: | 209 | val = 0; |
260 | if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ | 210 | else if (min_uV <= 1900000) |
261 | if (min_uV <= 1800000) | 211 | val = (min_uV - 1750001) / 50000; |
262 | val = 0; | 212 | else |
263 | else if (min_uV <= 1900000) | 213 | val = 3; /* 2700mV */ |
264 | val = (min_uV - 1750001) / 50000; | 214 | } else { /* 2700mV ~ 2850mV / 50mV */ |
265 | else | 215 | if (min_uV <= 2850000) { |
266 | val = 3; /* 2700mV */ | 216 | val = (min_uV - 2650001) / 50000; |
267 | else { /* 2700mV ~ 2900mV / 50mV */ | 217 | val += 3; |
268 | if (min_uV <= 2900000) { | 218 | } else if (min_uV <= 3300000) |
269 | val = (min_uV - 2650001) / 50000; | 219 | val = 7; |
270 | val += 3; | 220 | else |
271 | } else | 221 | val = -EINVAL; |
272 | val = -EINVAL; | ||
273 | } | ||
274 | break; | ||
275 | case PM8607_CHIP_B0: | ||
276 | if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ | ||
277 | if (min_uV <= 1800000) | ||
278 | val = 0; | ||
279 | else if (min_uV <= 1900000) | ||
280 | val = (min_uV - 1750001) / 50000; | ||
281 | else | ||
282 | val = 3; /* 2700mV */ | ||
283 | } else { /* 2700mV ~ 2850mV / 50mV */ | ||
284 | if (min_uV <= 2850000) { | ||
285 | val = (min_uV - 2650001) / 50000; | ||
286 | val += 3; | ||
287 | } else if (min_uV <= 3300000) | ||
288 | val = 7; | ||
289 | else | ||
290 | val = -EINVAL; | ||
291 | } | ||
292 | break; | ||
293 | } | 222 | } |
294 | break; | 223 | break; |
295 | case PM8607_ID_LDO4: | 224 | case PM8607_ID_LDO4: |
296 | switch (chip_id) { | 225 | if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ |
297 | case PM8607_CHIP_A0: | 226 | if (min_uV <= 1800000) |
298 | case PM8607_CHIP_A1: | 227 | val = 0; |
299 | if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ | 228 | else if (min_uV <= 1900000) |
300 | if (min_uV <= 1800000) | 229 | val = (min_uV - 1750001) / 50000; |
301 | val = 0; | 230 | else |
302 | else if (min_uV <= 1900000) | 231 | val = 3; /* 2700mV */ |
303 | val = (min_uV - 1750001) / 50000; | 232 | } else { /* 2700mV ~ 2800mV / 50mV */ |
304 | else | 233 | if (min_uV <= 2850000) { |
305 | val = 3; /* 2700mV */ | 234 | val = (min_uV - 2650001) / 50000; |
306 | else { /* 2700mV ~ 2900mV / 50mV */ | 235 | val += 3; |
307 | if (min_uV <= 2900000) { | 236 | } else if (min_uV <= 2900000) |
308 | val = (min_uV - 2650001) / 50000; | 237 | val = 6; |
309 | val += 3; | 238 | else if (min_uV <= 3300000) |
310 | } else | 239 | val = 7; |
311 | val = -EINVAL; | 240 | else |
312 | } | 241 | val = -EINVAL; |
313 | break; | ||
314 | case PM8607_CHIP_B0: | ||
315 | if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ | ||
316 | if (min_uV <= 1800000) | ||
317 | val = 0; | ||
318 | else if (min_uV <= 1900000) | ||
319 | val = (min_uV - 1750001) / 50000; | ||
320 | else | ||
321 | val = 3; /* 2700mV */ | ||
322 | } else { /* 2700mV ~ 2800mV / 50mV */ | ||
323 | if (min_uV <= 2850000) { | ||
324 | val = (min_uV - 2650001) / 50000; | ||
325 | val += 3; | ||
326 | } else if (min_uV <= 2900000) | ||
327 | val = 6; | ||
328 | else if (min_uV <= 3300000) | ||
329 | val = 7; | ||
330 | else | ||
331 | val = -EINVAL; | ||
332 | } | ||
333 | break; | ||
334 | } | 242 | } |
335 | break; | 243 | break; |
336 | case PM8607_ID_LDO6: | 244 | case PM8607_ID_LDO6: |
337 | switch (chip_id) { | 245 | if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */ |
338 | case PM8607_CHIP_A0: | 246 | if (min_uV <= 1800000) |
339 | case PM8607_CHIP_A1: | 247 | val = 0; |
340 | if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */ | 248 | else if (min_uV <= 1850000) |
341 | if (min_uV <= 1800000) | 249 | val = (min_uV - 1750001) / 50000; |
342 | val = 0; | 250 | else |
343 | else if (min_uV <= 1900000) | 251 | val = 2; /* 2600mV */ |
344 | val = (min_uV - 1750001) / 50000; | 252 | } else { /* 2600mV ~ 2800mV / 50mV */ |
345 | else | 253 | if (min_uV <= 2800000) { |
346 | val = 3; /* 2600mV */ | 254 | val = (min_uV - 2550001) / 50000; |
347 | } else { /* 2600mV ~ 2800mV / 50mV */ | 255 | val += 2; |
348 | if (min_uV <= 2800000) { | 256 | } else if (min_uV <= 3300000) |
349 | val = (min_uV - 2550001) / 50000; | 257 | val = 7; |
350 | val += 3; | 258 | else |
351 | } else | 259 | val = -EINVAL; |
352 | val = -EINVAL; | ||
353 | } | ||
354 | break; | ||
355 | case PM8607_CHIP_B0: | ||
356 | if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */ | ||
357 | if (min_uV <= 1800000) | ||
358 | val = 0; | ||
359 | else if (min_uV <= 1850000) | ||
360 | val = (min_uV - 1750001) / 50000; | ||
361 | else | ||
362 | val = 2; /* 2600mV */ | ||
363 | } else { /* 2600mV ~ 2800mV / 50mV */ | ||
364 | if (min_uV <= 2800000) { | ||
365 | val = (min_uV - 2550001) / 50000; | ||
366 | val += 2; | ||
367 | } else if (min_uV <= 3300000) | ||
368 | val = 7; | ||
369 | else | ||
370 | val = -EINVAL; | ||
371 | } | ||
372 | break; | ||
373 | } | 260 | } |
374 | break; | 261 | break; |
375 | case PM8607_ID_LDO14: | 262 | case PM8607_ID_LDO14: |
376 | switch (chip_id) { | 263 | if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */ |
377 | case PM8607_CHIP_A0: | 264 | if (min_uV <= 1800000) |
378 | case PM8607_CHIP_A1: | 265 | val = 0; |
379 | if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ | 266 | else if (min_uV <= 1850000) |
380 | if (min_uV <= 1800000) | 267 | val = (min_uV - 1750001) / 50000; |
381 | val = 0; | 268 | else |
382 | else if (min_uV <= 1900000) | 269 | val = 2; /* 2700mV */ |
383 | val = (min_uV - 1750001) / 50000; | 270 | } else { /* 2700mV ~ 2900mV / 50mV */ |
384 | else | 271 | if (min_uV <= 2900000) { |
385 | val = 3; /* 2700mV */ | 272 | val = (min_uV - 2650001) / 50000; |
386 | } else { /* 2700mV ~ 2900mV / 50mV */ | 273 | val += 2; |
387 | if (min_uV <= 2900000) { | 274 | } else if (min_uV <= 3300000) |
388 | val = (min_uV - 2650001) / 50000; | 275 | val = 7; |
389 | val += 3; | 276 | else |
390 | } else | 277 | val = -EINVAL; |
391 | val = -EINVAL; | ||
392 | } | ||
393 | break; | ||
394 | case PM8607_CHIP_B0: | ||
395 | if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */ | ||
396 | if (min_uV <= 1800000) | ||
397 | val = 0; | ||
398 | else if (min_uV <= 1850000) | ||
399 | val = (min_uV - 1750001) / 50000; | ||
400 | else | ||
401 | val = 2; /* 2700mV */ | ||
402 | } else { /* 2700mV ~ 2900mV / 50mV */ | ||
403 | if (min_uV <= 2900000) { | ||
404 | val = (min_uV - 2650001) / 50000; | ||
405 | val += 2; | ||
406 | } else if (min_uV <= 3300000) | ||
407 | val = 7; | ||
408 | else | ||
409 | val = -EINVAL; | ||
410 | } | ||
411 | break; | ||
412 | } | 278 | } |
413 | break; | 279 | break; |
414 | } | 280 | } |
@@ -428,7 +294,6 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, | |||
428 | int min_uV, int max_uV) | 294 | int min_uV, int max_uV) |
429 | { | 295 | { |
430 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 296 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
431 | struct pm8607_chip *chip = info->chip; | ||
432 | uint8_t val, mask; | 297 | uint8_t val, mask; |
433 | int ret; | 298 | int ret; |
434 | 299 | ||
@@ -443,13 +308,13 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, | |||
443 | val = (uint8_t)(ret << info->vol_shift); | 308 | val = (uint8_t)(ret << info->vol_shift); |
444 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 309 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
445 | 310 | ||
446 | ret = pm8607_set_bits(chip, info->vol_reg, mask, val); | 311 | ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val); |
447 | if (ret) | 312 | if (ret) |
448 | return ret; | 313 | return ret; |
449 | switch (info->desc.id) { | 314 | switch (info->desc.id) { |
450 | case PM8607_ID_BUCK1: | 315 | case PM8607_ID_BUCK1: |
451 | case PM8607_ID_BUCK3: | 316 | case PM8607_ID_BUCK3: |
452 | ret = pm8607_set_bits(chip, info->update_reg, | 317 | ret = pm860x_set_bits(info->i2c, info->update_reg, |
453 | 1 << info->update_bit, | 318 | 1 << info->update_bit, |
454 | 1 << info->update_bit); | 319 | 1 << info->update_bit); |
455 | break; | 320 | break; |
@@ -460,11 +325,10 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, | |||
460 | static int pm8607_get_voltage(struct regulator_dev *rdev) | 325 | static int pm8607_get_voltage(struct regulator_dev *rdev) |
461 | { | 326 | { |
462 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 327 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
463 | struct pm8607_chip *chip = info->chip; | ||
464 | uint8_t val, mask; | 328 | uint8_t val, mask; |
465 | int ret; | 329 | int ret; |
466 | 330 | ||
467 | ret = pm8607_reg_read(chip, info->vol_reg); | 331 | ret = pm860x_reg_read(info->i2c, info->vol_reg); |
468 | if (ret < 0) | 332 | if (ret < 0) |
469 | return ret; | 333 | return ret; |
470 | 334 | ||
@@ -477,9 +341,8 @@ static int pm8607_get_voltage(struct regulator_dev *rdev) | |||
477 | static int pm8607_enable(struct regulator_dev *rdev) | 341 | static int pm8607_enable(struct regulator_dev *rdev) |
478 | { | 342 | { |
479 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 343 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
480 | struct pm8607_chip *chip = info->chip; | ||
481 | 344 | ||
482 | return pm8607_set_bits(chip, info->enable_reg, | 345 | return pm860x_set_bits(info->i2c, info->enable_reg, |
483 | 1 << info->enable_bit, | 346 | 1 << info->enable_bit, |
484 | 1 << info->enable_bit); | 347 | 1 << info->enable_bit); |
485 | } | 348 | } |
@@ -487,19 +350,17 @@ static int pm8607_enable(struct regulator_dev *rdev) | |||
487 | static int pm8607_disable(struct regulator_dev *rdev) | 350 | static int pm8607_disable(struct regulator_dev *rdev) |
488 | { | 351 | { |
489 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 352 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
490 | struct pm8607_chip *chip = info->chip; | ||
491 | 353 | ||
492 | return pm8607_set_bits(chip, info->enable_reg, | 354 | return pm860x_set_bits(info->i2c, info->enable_reg, |
493 | 1 << info->enable_bit, 0); | 355 | 1 << info->enable_bit, 0); |
494 | } | 356 | } |
495 | 357 | ||
496 | static int pm8607_is_enabled(struct regulator_dev *rdev) | 358 | static int pm8607_is_enabled(struct regulator_dev *rdev) |
497 | { | 359 | { |
498 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 360 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
499 | struct pm8607_chip *chip = info->chip; | ||
500 | int ret; | 361 | int ret; |
501 | 362 | ||
502 | ret = pm8607_reg_read(chip, info->enable_reg); | 363 | ret = pm860x_reg_read(info->i2c, info->enable_reg); |
503 | if (ret < 0) | 364 | if (ret < 0) |
504 | return ret; | 365 | return ret; |
505 | 366 | ||
@@ -589,8 +450,8 @@ static inline struct pm8607_regulator_info *find_regulator_info(int id) | |||
589 | 450 | ||
590 | static int __devinit pm8607_regulator_probe(struct platform_device *pdev) | 451 | static int __devinit pm8607_regulator_probe(struct platform_device *pdev) |
591 | { | 452 | { |
592 | struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent); | 453 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
593 | struct pm8607_platform_data *pdata = chip->dev->platform_data; | 454 | struct pm860x_platform_data *pdata = chip->dev->platform_data; |
594 | struct pm8607_regulator_info *info = NULL; | 455 | struct pm8607_regulator_info *info = NULL; |
595 | 456 | ||
596 | info = find_regulator_info(pdev->id); | 457 | info = find_regulator_info(pdev->id); |
@@ -599,6 +460,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) | |||
599 | return -EINVAL; | 460 | return -EINVAL; |
600 | } | 461 | } |
601 | 462 | ||
463 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | ||
602 | info->chip = chip; | 464 | info->chip = chip; |
603 | 465 | ||
604 | info->regulator = regulator_register(&info->desc, &pdev->dev, | 466 | info->regulator = regulator_register(&info->desc, &pdev->dev, |