Changeset 3971
- Timestamp:
- 01/29/08 10:10:44 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/src/target/kernel/2.6.24.x/patches/gta02-acc.patch
r3970 r3971 25 25 static struct glamo_spigpio_info glamo_spigpio_cfg = { 26 26 .pin_clk = GLAMO_GPIO10_OUTPUT, 27 @@ -504,16 +504, 13 @@27 @@ -504,16 +504,93 @@ 28 28 29 29 /* SPI: Accelerometers attached to SPI of s3c244x */ 30 30 31 31 -static void gta02_spi_acc_set_cs(struct s3c2410_spi_info *spi, int cs, int pol) 32 -{ 32 +/* 33 + * Situation is that Linux SPI can't work in an interrupt context, so we 34 + * implement our own bitbang here. Arbitration is needed because not only 35 + * can this interrupt happen at any time even if foreground wants to use 36 + * the bitbang API from Linux, but multiple motion sensors can be on the 37 + * same SPI bus, and multiple interrupts can happen. 38 + * 39 + * Foreground / interrupt arbitration is okay because the interrupts are 40 + * disabled around all the foreground SPI code. 41 + * 42 + * Interrupt / Interrupt arbitration is okay because the interrupts are 43 + * at the same priority (I think) 44 + * 45 + * Servicing is typ 75 - 100us at 400MHz. 46 + */ 47 + 48 +/* #define DEBUG_SPEW_MS */ 49 +#define MG_PER_SAMPLE 18 50 + 51 +void gat02_lis302dl_bitbang_read(struct lis302dl_info *lis) 52 { 33 53 - s3c2410_gpio_setpin(cs, pol); 34 -} 35 - 36 static const struct lis302dl_platform_data lis302_pdata[] = { 54 + struct lis302dl_platform_data *pdata = lis->pdata; 55 + u8 shifter = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */ 56 + int n, n1; 57 +#ifdef DEBUG_SPEW_MS 58 + s8 x, y, z; 59 +#endif 60 + 61 + s3c2410_gpio_setpin(pdata->pin_chip_select, 0); 62 + for (n = 0; n < 8; n++) { /* write the r/w, inc and address */ 63 + s3c2410_gpio_setpin(pdata->pin_clk, 0); 64 + s3c2410_gpio_setpin(pdata->pin_mosi, (shifter >> 7) & 1); 65 + s3c2410_gpio_setpin(pdata->pin_clk, 1); 66 + shifter <<= 1; 67 + } 68 + for (n = 0; n < 5; n++) { /* 5 consequetive registers */ 69 + for (n1 = 0; n1 < 8; n1++) { /* 8 bits each */ 70 + s3c2410_gpio_setpin(pdata->pin_clk, 0); 71 + s3c2410_gpio_setpin(pdata->pin_clk, 1); 72 + shifter <<= 1; 73 + if (s3c2410_gpio_getpin(pdata->pin_miso)) 74 + shifter |= 1; 75 + } 76 + switch (n) { 77 + case 0: 78 +#ifdef DEBUG_SPEW_MS 79 + x = shifter; 80 +#endif 81 + input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)shifter); 82 + break; 83 + case 2: 84 +#ifdef DEBUG_SPEW_MS 85 + y = shifter; 86 +#endif 87 + input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)shifter); 88 + break; 89 + case 4: 90 +#ifdef DEBUG_SPEW_MS 91 + z = shifter; 92 +#endif 93 + input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)shifter); 94 + break; 95 + } 96 + } 97 + s3c2410_gpio_setpin(pdata->pin_chip_select, 1); 98 + input_sync(lis->input_dev); 99 +#ifdef DEBUG_SPEW_MS 100 + printk("%s: %d %d %d\n", pdata->name, x, y, z); 101 +#endif 102 } 103 104 -static const struct lis302dl_platform_data lis302_pdata[] = { 105 + 106 +const struct lis302dl_platform_data lis302_pdata[] = { 37 107 { 38 108 - .name = "lis302-1 (top)" 39 109 + .name = "lis302-1 (top)", 40 110 + .pin_chip_select= S3C2410_GPD12, 111 + .pin_clk = S3C2410_GPG7, 112 + .pin_mosi = S3C2410_GPG6, 113 + .pin_miso = S3C2410_GPG5, 114 + .lis302dl_bitbang_read = gat02_lis302dl_bitbang_read, 41 115 }, { 42 116 - .name = "lis302-2 (bottom)" 43 117 + .name = "lis302-2 (bottom)", 44 118 + .pin_chip_select= S3C2410_GPD13, 119 + .pin_clk = S3C2410_GPG7, 120 + .pin_mosi = S3C2410_GPG6, 121 + .pin_miso = S3C2410_GPG5, 122 + .lis302dl_bitbang_read = gat02_lis302dl_bitbang_read, 45 123 }, 46 124 }; 47 125 48 @@ -522,26 +5 19,75 @@126 @@ -522,26 +599,75 @@ 49 127 .modalias = "lis302dl", 50 128 .platform_data = &lis302_pdata[0], … … 128 206 129 207 static struct resource gta02_led_resources[] = { 130 @@ -784,7 + 830,6 @@208 @@ -784,7 +910,6 @@ 131 209 s3c_device_usb.dev.platform_data = >a02_usb_info; 132 210 s3c_device_nand.dev.platform_data = >a02_nand_info; … … 136 214 /* Only GTA02v1 has a SD_DETECT GPIO. Since the slot is not 137 215 * hot-pluggable, this is not required anyway */ 138 @@ -796,6 + 841,12 @@216 @@ -796,6 +921,12 @@ 139 217 break; 140 218 } … … 149 227 s3c24xx_udc_set_platdata(>a02_udc_cfg); 150 228 set_s3c2410ts_info(>a02_ts_cfg); 151 @@ -824,6 + 875,7 @@229 @@ -824,6 +955,7 @@ 152 230 break; 153 231 } … … 161 239 --- linux-2.6.24.orig/drivers/input/misc/lis302dl.c 162 240 +++ linux-2.6.24/drivers/input/misc/lis302dl.c 163 @@ -84,6 +84,7 @@ 164 165 enum lis302dl_reg_ctrl3 { 166 LIS302DL_CTRL3_PP_OD = 0x40, 167 + LIS302DL_CTRL3_IHL = 0x80, 168 }; 169 170 enum lis302dl_reg_status { 171 @@ -134,16 +135,17 @@ 172 241 @@ -33,117 +33,26 @@ 242 #include <linux/device.h> 243 #include <linux/platform_device.h> 244 #include <linux/delay.h> 245 -#include <linux/input.h> 246 #include <linux/irq.h> 247 #include <linux/interrupt.h> 248 #include <linux/sysfs.h> 249 250 #include <linux/lis302dl.h> 251 252 -#include <linux/spi/spi.h> 253 - 254 -#define LIS302DL_WHO_AM_I_MAGIC 0x3b 255 - 256 -enum lis302dl_reg { 257 - LIS302DL_REG_WHO_AM_I = 0x0f, 258 - LIS302DL_REG_CTRL1 = 0x20, 259 - LIS302DL_REG_CTRL2 = 0x21, 260 - LIS302DL_REG_CTRL3 = 0x22, 261 - LIS302DL_REG_HP_FILTER_RESET = 0x23, 262 - LIS302DL_REG_STATUS = 0x27, 263 - LIS302DL_REG_OUT_X = 0x29, 264 - LIS302DL_REG_OUT_Y = 0x2b, 265 - LIS302DL_REG_OUT_Z = 0x2d, 266 - LIS302DL_REG_FF_WU_CFG_1 = 0x30, 267 - LIS302DL_REG_FF_WU_SRC_1 = 0x31, 268 - LIS302DL_REG_FF_WU_THS_1 = 0x32, 269 - LIS302DL_REG_FF_WU_DURATION_1 = 0x33, 270 - LIS302DL_REG_FF_WU_CFG_2 = 0x34, 271 - LIS302DL_REG_FF_WU_SRC_2 = 0x35, 272 - LIS302DL_REG_FF_WU_THS_2 = 0x36, 273 - LIS302DL_REG_FF_WU_DURATION_2 = 0x37, 274 - LIS302DL_REG_CLICK_CFG = 0x38, 275 - LIS302DL_REG_CLICK_SRC = 0x39, 276 - LIS302DL_REG_CLICK_THSY_X = 0x3b, 277 - LIS302DL_REG_CLICK_THSZ = 0x3c, 278 - LIS302DL_REG_CLICK_TIME_LIMIT = 0x3d, 279 - LIS302DL_REG_CLICK_LATENCY = 0x3e, 280 - LIS302DL_REG_CLICK_WINDOW = 0x3f, 281 -}; 282 - 283 -enum lis302dl_reg_ctrl1 { 284 - LIS302DL_CTRL1_Xen = 0x01, 285 - LIS302DL_CTRL1_Yen = 0x02, 286 - LIS302DL_CTRL1_Zen = 0x04, 287 - LIS302DL_CTRL1_STM = 0x08, 288 - LIS302DL_CTRL1_STP = 0x10, 289 - LIS302DL_CTRL1_FS = 0x20, 290 - LIS302DL_CTRL1_PD = 0x40, 291 - LIS302DL_CTRL1_DR = 0x80, 292 -}; 293 - 294 -enum lis302dl_reg_ctrl3 { 295 - LIS302DL_CTRL3_PP_OD = 0x40, 296 -}; 297 - 298 -enum lis302dl_reg_status { 299 - LIS302DL_STATUS_XDA = 0x01, 300 - LIS302DL_STATUS_YDA = 0x02, 301 - LIS302DL_STATUS_ZDA = 0x04, 302 - LIS302DL_STATUS_XYZDA = 0x08, 303 - LIS302DL_STATUS_XOR = 0x10, 304 - LIS302DL_STATUS_YOR = 0x20, 305 - LIS302DL_STATUS_ZOR = 0x40, 306 - LIS302DL_STATUS_XYZOR = 0x80, 307 -}; 308 - 309 -enum lis302dl_reg_ffwusrc1 { 310 - LIS302DL_FFWUSRC1_XL = 0x01, 311 - LIS302DL_FFWUSRC1_XH = 0x02, 312 - LIS302DL_FFWUSRC1_YL = 0x04, 313 - LIS302DL_FFWUSRC1_YH = 0x08, 314 - LIS302DL_FFWUSRC1_ZL = 0x10, 315 - LIS302DL_FFWUSRC1_ZH = 0x20, 316 - LIS302DL_FFWUSRC1_IA = 0x40, 317 -}; 318 - 319 -enum lis302dl_reg_cloik_src { 320 - LIS302DL_CLICKSRC_SINGLE_X = 0x01, 321 - LIS302DL_CLICKSRC_DOUBLE_X = 0x02, 322 - LIS302DL_CLICKSRC_SINGLE_Y = 0x04, 323 - LIS302DL_CLICKSRC_DOUBLE_Y = 0x08, 324 - LIS302DL_CLICKSRC_SINGLE_Z = 0x10, 325 - LIS302DL_CLICKSRC_DOUBLE_Z = 0x20, 326 - LIS302DL_CLICKSRC_IA = 0x40, 327 -}; 328 - 329 -struct lis302dl_info { 330 - struct spi_device *spi_dev; 331 - struct input_dev *input_dev; 332 - struct mutex lock; 333 - struct work_struct work; 334 - unsigned int flags; 335 - unsigned int working; 336 - u_int8_t regs[0x40]; 337 -}; 338 - 339 -#define LIS302DL_F_WUP_FF 0x0001 /* wake up from free fall */ 340 -#define LIS302DL_F_WUP_CLICK 0x0002 341 -#define LIS302DL_F_POWER 0x0010 342 -#define LIS302DL_F_FS 0x0020 /* ADC full scale */ 343 - 173 344 /* lowlevel register access functions */ 174 345 … … 176 347 -#define MS_BIT 0x02 177 348 -#define ADDR_SHIFT 2 178 +#define READ_BIT 0x80 179 +#define ADDR_MASK 0x3f 349 +#define READ_BIT 0x80 350 +#define READ_BIT_INC_ADS 0xc0 351 +#define ADDR_MASK 0x3f 180 352 181 353 -static inline u_int8_t __reg_read(struct lis302dl_info *lis, u_int8_t reg) … … 192 364 rc = spi_w8r8(lis->spi_dev, cmd); 193 365 194 @@ -161,11 + 163,13 @@366 @@ -161,11 +70,13 @@ 195 367 return ret; 196 368 } … … 208 380 209 381 return spi_write(lis->spi_dev, buf, sizeof(buf)); 210 @@ -207,10 + 211,10 @@382 @@ -207,10 +118,10 @@ 211 383 enum lis302dl_intmode { 212 384 LIS302DL_INTMODE_GND = 0x00, … … 223 395 224 396 static void lis302dl_int_mode(struct spi_device *spi, int int_pin, 225 @@ -218,1 0 +222,16@@397 @@ -218,12 +129,18 @@ 226 398 { 227 399 struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); … … 240 412 + } 241 413 } 242 414 - 415 +#if 0 243 416 static void _report_btn_single(struct input_dev *inp, int btn) 244 @@ -247,34 +257,30 @@ 245 struct lis302dl_info *lis = 246 container_of(work, struct lis302dl_info, work); 247 417 { 418 input_report_key(inp, btn, 1); 419 @@ -241,95 +158,14 @@ 420 input_sync(inp); 421 input_report_key(inp, btn, 0); 422 } 423 +#endif 424 425 -static void lis302dl_work(struct work_struct *work) 426 -{ 427 - struct lis302dl_info *lis = 428 - container_of(work, struct lis302dl_info, work); 429 - 248 430 - u_int8_t status, ff_wu_src_1, click_src; 249 431 - u_int8_t val; 250 + u_int8_t status, ff_wu_src_1, ff_wu_src_2, click_src; 251 + u_int8_t val_x, val_y, val_z; 252 253 lis->working = 1; 254 255 status = reg_read(lis, LIS302DL_REG_STATUS); 256 ff_wu_src_1 = reg_read(lis, LIS302DL_REG_FF_WU_SRC_1); 257 + ff_wu_src_2 = reg_read(lis, LIS302DL_REG_FF_WU_SRC_2); 258 click_src = reg_read(lis, LIS302DL_REG_CLICK_SRC); 259 432 - 433 - lis->working = 1; 434 - 435 - status = reg_read(lis, LIS302DL_REG_STATUS); 436 - ff_wu_src_1 = reg_read(lis, LIS302DL_REG_FF_WU_SRC_1); 437 - click_src = reg_read(lis, LIS302DL_REG_CLICK_SRC); 438 - 260 439 - if (status & LIS302DL_STATUS_XDA) { 261 440 - val = reg_read(lis, LIS302DL_REG_OUT_X); 262 + if (status & LIS302DL_STATUS_XYZDA) { 263 + val_x = reg_read(lis, LIS302DL_REG_OUT_X); 264 if (lis->flags & LIS302DL_F_FS) 441 - if (lis->flags & LIS302DL_F_FS) 265 442 - val = val << 2; 266 443 - input_report_rel(lis->input_dev, REL_X, val); … … 269 446 - if (status & LIS302DL_STATUS_YDA) { 270 447 - val = reg_read(lis, LIS302DL_REG_OUT_Y); 271 + val_x = val_x << 2; 272 + input_report_rel(lis->input_dev, REL_X, val_x); 273 + val_y = reg_read(lis, LIS302DL_REG_OUT_Y); 274 if (lis->flags & LIS302DL_F_FS) 448 - if (lis->flags & LIS302DL_F_FS) 275 449 - val = val << 2; 276 450 - input_report_rel(lis->input_dev, REL_Y, val); … … 279 453 - if (status & LIS302DL_STATUS_ZDA) { 280 454 - val = reg_read(lis, LIS302DL_REG_OUT_Z); 281 + val_y = val_y << 2; 282 + input_report_rel(lis->input_dev, REL_Y, val_y); 283 + val_z = reg_read(lis, LIS302DL_REG_OUT_Z); 284 if (lis->flags & LIS302DL_F_FS) 455 - if (lis->flags & LIS302DL_F_FS) 285 456 - val = val << 2; 286 457 - input_report_rel(lis->input_dev, REL_Z, val); 287 + val_z = val_z << 2; 288 + input_report_rel(lis->input_dev, REL_Z, val_z); 289 +// printk("%p: x=%d, y=%d, z=%d\n", lis, val_x, val_y, val_z); 290 } 291 292 if (status & 0xf0) 293 @@ -310,21 +316,15 @@ 294 enable_irq(lis->spi_dev->irq); 295 } 296 458 - } 459 - 460 - if (status & 0xf0) 461 - dev_dbg(&lis->spi_dev->dev, "overrun!\n"); 462 - 463 - /* FIXME: implement overrun statistics */ 464 - 465 - if (ff_wu_src_1 & LIS302DL_FFWUSRC1_IA) { 466 - /* FIXME: free fall interrupt handling */ 467 - } 468 - 469 - if (click_src & LIS302DL_CLICKSRC_IA) { 470 - if (click_src & LIS302DL_CLICKSRC_SINGLE_X) 471 - _report_btn_single(lis->input_dev, BTN_X); 472 - if (click_src & LIS302DL_CLICKSRC_DOUBLE_X) 473 - _report_btn_double(lis->input_dev, BTN_X); 474 - 475 - if (click_src & LIS302DL_CLICKSRC_SINGLE_Y) 476 - _report_btn_single(lis->input_dev, BTN_Y); 477 - if (click_src & LIS302DL_CLICKSRC_DOUBLE_Y) 478 - _report_btn_double(lis->input_dev, BTN_Y); 479 - 480 - if (click_src & LIS302DL_CLICKSRC_SINGLE_Z) 481 - _report_btn_single(lis->input_dev, BTN_Z); 482 - if (click_src & LIS302DL_CLICKSRC_DOUBLE_Z) 483 - _report_btn_double(lis->input_dev, BTN_Z); 484 - } 485 - 486 - lis->working = 0; 487 - input_sync(lis->input_dev); 488 - put_device(&lis->spi_dev->dev); 489 - 490 - enable_irq(lis->spi_dev->irq); 491 -} 492 - 297 493 -static void lis302dl_schedule_work(struct lis302dl_info *lis) 298 494 -{ … … 304 500 - dev_dbg(&lis->spi_dev->dev, "work item may be lost\n"); 305 501 -} 306 - 502 307 503 static irqreturn_t lis302dl_interrupt(int irq, void *_lis) 308 504 { … … 310 506 311 507 - lis302dl_schedule_work(lis); 312 + get_device(&lis->spi_dev->dev); 313 + 314 + if (!schedule_work(&lis->work)) 315 + if (!lis->working) 316 + dev_dbg(&lis->spi_dev->dev, "work item may be lost\n"); 317 318 /* Disable any further interrupts until we have processed 319 * the current one */ 320 @@ -388,6 +388,7 @@ 508 - 509 - /* Disable any further interrupts until we have processed 510 - * the current one */ 511 - disable_irq(lis->spi_dev->irq); 512 - 513 + (lis->pdata->lis302dl_bitbang_read)(lis); 514 return IRQ_HANDLED; 515 } 516 517 @@ -388,6 +224,7 @@ 321 518 static struct attribute *lis302dl_sysfs_entries[] = { 322 519 &dev_attr_sample_rate.attr, … … 326 523 327 524 static struct attribute_group lis302dl_attr_group = { 328 @@ -416,7 +417,7 @@ 525 @@ -402,9 +239,16 @@ 526 struct lis302dl_info *lis = inp->private; 527 u_int8_t ctrl1 = LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen | 528 LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen; 529 + unsigned long flags; 530 531 + local_save_flags(flags); 532 /* make sure we're powered up and generate data ready */ 533 reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1); 534 + local_irq_restore(flags); 535 + 536 + /* kick it off -- since we are edge triggered, if we missed the edge 537 + * permanent low interrupt is death for us */ 538 + (lis->pdata->lis302dl_bitbang_read)(lis); 539 540 return 0; 541 } 542 @@ -414,9 +258,12 @@ 543 struct lis302dl_info *lis = inp->private; 544 u_int8_t ctrl1 = LIS302DL_CTRL1_Xen | LIS302DL_CTRL1_Yen | 329 545 LIS302DL_CTRL1_Zen; 546 + unsigned long flags; 547 + 548 + local_save_flags(flags); 330 549 331 550 /* since the input core already serializes access and makes sure we … … 335 554 reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00); 336 555 337 @@ -446,44 +447,38 @@ 338 556 @@ -426,6 +273,7 @@ 557 reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD, 558 0x00); 559 } 560 + local_irq_restore(flags); 561 } 562 563 static int __devinit lis302dl_probe(struct spi_device *spi) 564 @@ -433,84 +281,133 @@ 565 int rc; 566 struct lis302dl_info *lis; 567 u_int8_t wai; 568 + unsigned long flags; 569 + struct lis302dl_platform_data *pdata; 570 571 lis = kzalloc(sizeof(*lis), GFP_KERNEL); 572 if (!lis) 573 return -ENOMEM; 574 575 + local_save_flags(flags); 576 + 577 mutex_init(&lis->lock); 578 - INIT_WORK(&lis->work, lis302dl_work); 579 lis->spi_dev = spi; 580 581 spi_set_drvdata(spi, lis); 582 583 + pdata = spi->dev.platform_data; 584 + 339 585 rc = spi_setup(spi); 340 586 if (rc < 0) { … … 354 600 - kfree(lis); 355 601 - return -ENODEV; 356 + rc = -ENODEV; 357 + goto bail_free_lis; 358 } 359 602 - } 603 - 360 604 - /* switch interrupt to open collector */ 361 605 - reg_write(lis, LIS302DL_CTRL3_PP_OD, 0x7c); … … 363 607 - rc = request_irq(lis->spi_dev->irq, lis302dl_interrupt, IRQF_DISABLED, 364 608 - "lis302dl", NULL); 365 + rc = request_irq(lis->spi_dev->irq, lis302dl_interrupt, 366 + IRQF_TRIGGER_LOW, "lis302dl", lis); 367 if (rc < 0) { 368 dev_err(&spi->dev, "error requesting IRQ %d\n", 369 lis->spi_dev->irq); 609 - if (rc < 0) { 610 - dev_err(&spi->dev, "error requesting IRQ %d\n", 611 - lis->spi_dev->irq); 370 612 - /* FIXME */ 371 613 - return rc; 614 + rc = -ENODEV; 372 615 + goto bail_free_lis; 373 616 } … … 378 621 - /* FIXME */ 379 622 - return rc; 380 + goto bail_ irq;623 + goto bail_free_lis; 381 624 } 382 625 … … 390 633 391 634 set_bit(EV_REL, lis->input_dev->evbit); 392 @@ -498,9 +493,44 @@ 635 - set_bit(EV_KEY, lis->input_dev->evbit); 636 + set_bit(REL_X, lis->input_dev->relbit); 637 + set_bit(REL_Y, lis->input_dev->relbit); 638 + set_bit(REL_Z, lis->input_dev->relbit); 639 +/* set_bit(EV_KEY, lis->input_dev->evbit); 640 set_bit(BTN_X, lis->input_dev->keybit); 641 set_bit(BTN_Y, lis->input_dev->keybit); 642 set_bit(BTN_Z, lis->input_dev->keybit); 643 - 644 +*/ 645 lis->input_dev->private = lis; 646 - lis->input_dev->name = "lis302dl"; /* FIXME: platform data */ 647 - lis->input_dev->id.bustype = BUS_I2C; /* FIXME: SPI Bus */ 648 + lis->input_dev->name = pdata->name; 649 + /* SPI Bus not defined as a valid bus for input subsystem*/ 650 + lis->input_dev->id.bustype = BUS_I2C; /* lie about it */ 393 651 lis->input_dev->open = lis302dl_input_open; 394 652 lis->input_dev->close = lis302dl_input_close; … … 421 679 + reg_read(lis, LIS302DL_REG_FF_WU_SRC_2); 422 680 + reg_read(lis, LIS302DL_REG_CLICK_SRC); 423 681 + 682 + dev_info(&spi->dev, "Found %s\n", pdata->name); 683 684 + lis->pdata = pdata; 685 + 686 + rc = request_irq(lis->spi_dev->irq, lis302dl_interrupt, 687 + IRQF_TRIGGER_FALLING, "lis302dl", lis); 688 + if (rc < 0) { 689 + dev_err(&spi->dev, "error requesting IRQ %d\n", 690 + lis->spi_dev->irq); 691 + goto bail_inp_reg; 692 + } 693 + local_irq_restore(flags); 424 694 return 0; 425 695 + 696 +bail_inp_reg: 697 + input_unregister_device(lis->input_dev); 426 698 +bail_inp_dev: 427 699 + input_free_device(lis->input_dev); 428 700 +bail_sysfs: 429 701 + sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group); 430 +bail_irq:431 + free_irq(lis->spi_dev->irq, NULL);432 702 +bail_free_lis: 433 703 + kfree(lis); 704 + local_irq_restore(flags); 434 705 + return rc; 435 706 } 436 707 437 708 static int __devexit lis302dl_remove(struct spi_device *spi) 438 @@ -511,6 +541,8 @@ 709 { 710 struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); 711 + unsigned long flags; 712 713 /* power down the device */ 714 + local_save_flags(flags); 439 715 reg_write(lis, LIS302DL_REG_CTRL1, 0x00); 716 + local_irq_restore(flags); 717 + 440 718 sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group); 441 719 input_unregister_device(lis->input_dev); … … 445 723 kfree(lis); 446 724 725 @@ -521,6 +418,9 @@ 726 static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) 727 { 728 struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); 729 + unsigned long flags; 730 + 731 + local_save_flags(flags); 732 733 /* save registers */ 734 lis->regs[LIS302DL_REG_CTRL1] = reg_read(lis, LIS302DL_REG_CTRL1); 735 @@ -561,12 +461,17 @@ 736 reg_write(lis, LIS302DL_REG_CTRL1, tmp); 737 } 738 739 + local_irq_restore(flags); 740 + 741 return 0; 742 } 743 744 static int lis302dl_resume(struct spi_device *spi) 745 { 746 struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); 747 + unsigned long flags; 748 + 749 + local_save_flags(flags); 750 751 /* restore registers after resume */ 752 reg_write(lis, LIS302DL_REG_CTRL1, lis->regs[LIS302DL_REG_CTRL1]); 753 @@ -597,6 +502,8 @@ 754 reg_write(lis, LIS302DL_REG_CLICK_WINDOW, 755 lis->regs[LIS302DL_REG_CLICK_WINDOW]); 756 757 + local_irq_restore(flags); 758 + 759 return 0; 760 } 761 #else 447 762 Index: linux-2.6.24/drivers/spi/spi_s3c24xx_gpio.c 448 763 =================================================================== … … 512 827 --- linux-2.6.24.orig/include/linux/lis302dl.h 513 828 +++ linux-2.6.24/include/linux/lis302dl.h 514 @@ -5,6 +5,7 @@ 829 @@ -2,10 +2,111 @@ 830 #define _LINUX_LIS302DL_H 831 832 #include <linux/types.h> 833 +#include <linux/spi/spi.h> 834 +#include <linux/input.h> 835 + 836 + 837 +struct lis302dl_info; 515 838 516 839 struct lis302dl_platform_data { 517 840 char *name; 518 841 + unsigned long pin_chip_select; 519 }; 520 842 + unsigned long pin_clk; 843 + unsigned long pin_mosi; 844 + unsigned long pin_miso; 845 + void (*lis302dl_bitbang_read)(struct lis302dl_info *); 846 +}; 847 + 848 +struct lis302dl_info { 849 + struct lis302dl_platform_data *pdata; 850 + struct spi_device *spi_dev; 851 + struct input_dev *input_dev; 852 + struct mutex lock; 853 + unsigned int flags; 854 + u_int8_t regs[0x40]; 855 +}; 856 + 857 +enum lis302dl_reg { 858 + LIS302DL_REG_WHO_AM_I = 0x0f, 859 + LIS302DL_REG_CTRL1 = 0x20, 860 + LIS302DL_REG_CTRL2 = 0x21, 861 + LIS302DL_REG_CTRL3 = 0x22, 862 + LIS302DL_REG_HP_FILTER_RESET = 0x23, 863 + LIS302DL_REG_STATUS = 0x27, 864 + LIS302DL_REG_OUT_X = 0x29, 865 + LIS302DL_REG_OUT_Y = 0x2b, 866 + LIS302DL_REG_OUT_Z = 0x2d, 867 + LIS302DL_REG_FF_WU_CFG_1 = 0x30, 868 + LIS302DL_REG_FF_WU_SRC_1 = 0x31, 869 + LIS302DL_REG_FF_WU_THS_1 = 0x32, 870 + LIS302DL_REG_FF_WU_DURATION_1 = 0x33, 871 + LIS302DL_REG_FF_WU_CFG_2 = 0x34, 872 + LIS302DL_REG_FF_WU_SRC_2 = 0x35, 873 + LIS302DL_REG_FF_WU_THS_2 = 0x36, 874 + LIS302DL_REG_FF_WU_DURATION_2 = 0x37, 875 + LIS302DL_REG_CLICK_CFG = 0x38, 876 + LIS302DL_REG_CLICK_SRC = 0x39, 877 + LIS302DL_REG_CLICK_THSY_X = 0x3b, 878 + LIS302DL_REG_CLICK_THSZ = 0x3c, 879 + LIS302DL_REG_CLICK_TIME_LIMIT = 0x3d, 880 + LIS302DL_REG_CLICK_LATENCY = 0x3e, 881 + LIS302DL_REG_CLICK_WINDOW = 0x3f, 882 +}; 883 + 884 +enum lis302dl_reg_ctrl1 { 885 + LIS302DL_CTRL1_Xen = 0x01, 886 + LIS302DL_CTRL1_Yen = 0x02, 887 + LIS302DL_CTRL1_Zen = 0x04, 888 + LIS302DL_CTRL1_STM = 0x08, 889 + LIS302DL_CTRL1_STP = 0x10, 890 + LIS302DL_CTRL1_FS = 0x20, 891 + LIS302DL_CTRL1_PD = 0x40, 892 + LIS302DL_CTRL1_DR = 0x80, 893 +}; 894 + 895 +enum lis302dl_reg_ctrl3 { 896 + LIS302DL_CTRL3_PP_OD = 0x40, 897 + LIS302DL_CTRL3_IHL = 0x80, 898 }; 899 900 +enum lis302dl_reg_status { 901 + LIS302DL_STATUS_XDA = 0x01, 902 + LIS302DL_STATUS_YDA = 0x02, 903 + LIS302DL_STATUS_ZDA = 0x04, 904 + LIS302DL_STATUS_XYZDA = 0x08, 905 + LIS302DL_STATUS_XOR = 0x10, 906 + LIS302DL_STATUS_YOR = 0x20, 907 + LIS302DL_STATUS_ZOR = 0x40, 908 + LIS302DL_STATUS_XYZOR = 0x80, 909 +}; 910 + 911 +enum lis302dl_reg_ffwusrc1 { 912 + LIS302DL_FFWUSRC1_XL = 0x01, 913 + LIS302DL_FFWUSRC1_XH = 0x02, 914 + LIS302DL_FFWUSRC1_YL = 0x04, 915 + LIS302DL_FFWUSRC1_YH = 0x08, 916 + LIS302DL_FFWUSRC1_ZL = 0x10, 917 + LIS302DL_FFWUSRC1_ZH = 0x20, 918 + LIS302DL_FFWUSRC1_IA = 0x40, 919 +}; 920 + 921 +enum lis302dl_reg_cloik_src { 922 + LIS302DL_CLICKSRC_SINGLE_X = 0x01, 923 + LIS302DL_CLICKSRC_DOUBLE_X = 0x02, 924 + LIS302DL_CLICKSRC_SINGLE_Y = 0x04, 925 + LIS302DL_CLICKSRC_DOUBLE_Y = 0x08, 926 + LIS302DL_CLICKSRC_SINGLE_Z = 0x10, 927 + LIS302DL_CLICKSRC_DOUBLE_Z = 0x20, 928 + LIS302DL_CLICKSRC_IA = 0x40, 929 +}; 930 + 931 +#define LIS302DL_WHO_AM_I_MAGIC 0x3b 932 + 933 +#define LIS302DL_F_WUP_FF 0x0001 /* wake up from free fall */ 934 +#define LIS302DL_F_WUP_CLICK 0x0002 935 +#define LIS302DL_F_POWER 0x0010 936 +#define LIS302DL_F_FS 0x0020 /* ADC full scale */ 937 + 938 + 521 939 #endif /* _LINUX_LIS302DL_H */ 940 522 941 Index: linux-2.6.24/arch/arm/mach-s3c2410/mach-gta01.c 523 942 ===================================================================
Note: See TracChangeset
for help on using the changeset viewer.
