陀螺仪_SPI
基于内核spi驱动修改移植
1 /* 2 * Simple synchronous userspace interface to SPI devices 3 * 4 * Copyright (C) 2006 SWAPP 5 * Andrea Paterniani6 * Copyright (C) 2007 David Brownell (simplification, cleanup) 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 #include 24 #include 25 #include 26 #include 27 #include 28 #include 29 #include 30 #include 31 #include 32 #include 33 #include 34 35 #include 36 #include 37 #include 38 #include 39 40 //struct spidev_data spidev0; 41 42 43 /********************************* mpu6500 *********************************************/ 44 45 46 #define MPU6500_MAGIC 'K' 47 48 //用于读取数据的存储 49 50 union mpu6500_data 51 { 52 struct { 53 short x; 54 short y; 55 short z; 56 }accel; 57 struct { 58 short x; 59 short y; 60 short z; 61 }gyro; 62 unsigned short temp; 63 }; 64 65 66 67 #define GET_ACCEL _IOR(MPU6500_MAGIC, 0, union mpu6500_data) 68 #define GET_GYRO _IOR(MPU6500_MAGIC, 1, union mpu6500_data) 69 #define GET_TEMP _IOR(MPU6500_MAGIC, 2, union mpu6500_data) 70 71 72 #define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz) 73 #define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz) 74 #define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s) 75 #define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波,典型值:0x18(不自检,2G,5Hz) 76 77 78 // 注册59到64 -加速度计测量值 79 #define ACCEL_XOUT_H 0x3B //加速度计x轴数据的高字节 80 #define ACCEL_XOUT_L 0x3C //加速度计x轴数据的低字节 81 #define ACCEL_YOUT_H 0x3D //加速度计y轴数据的高字节 82 #define ACCEL_YOUT_L 0x3E //加速度计y轴数据的低字节 83 #define ACCEL_ZOUT_H 0x3F //加速度计z轴数据的高字节 84 #define ACCEL_ZOUT_L 0x40 //加速度计z轴数据的低字节 85 86 87 // 寄存器65和66 -温度测量 88 #define TEMP_OUT_H 0x41 //温度传感器输出的高字节 89 #define TEMP_OUT_L 0x42 //温度传感器输出的低字节 90 91 92 // 注册67至72 -陀螺仪测量 93 #define GYRO_XOUT_H 0x43 //高字节的x轴陀螺仪输出 94 #define GYRO_XOUT_L 0x44 //低字节的x轴陀螺仪输出 95 #define GYRO_YOUT_H 0x45 //高字节的y轴陀螺仪输出 96 #define GYRO_YOUT_L 0x46 //低字节的y轴陀螺仪输出 97 #define GYRO_ZOUT_H 0x47 //高字节的z轴陀螺仪输出 98 #define GYRO_ZOUT_L 0x48 //低字节的z轴陀螺仪输出 99 100 101 #define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用) 102 #define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读) 103 #define SlaveAddress 0x68 //MPU6050-I2C地址寄存器 104 105 106 /********************************* mpu6500 *********************************************/ 107 108 109 110 /* 111 * This supports access to SPI devices using normal userspace I/O calls. 112 * Note that while traditional UNIX/POSIX I/O semantics are half duplex, 113 * and often mask message boundaries, full SPI support requires full duplex 114 * transfers. There are several kinds of internal message boundaries to 115 * handle chipselect management and other protocol options. 116 * 117 * SPI has a character major number assigned. We allocate minor numbers 118 * dynamically using a bitmask. You must use hotplug tools, such as udev 119 * (or mdev with busybox) to create and destroy the /dev/spidevB.C device 120 * nodes, since there is no fixed association of minor numbers with any 121 * particular SPI bus or device. 122 */ 123 #define SPIDEV_MAJOR 153 /* assigned */ 124 #define N_SPI_MINORS 32 /* ... up to 256 */ 125 126 static DECLARE_BITMAP(minors, N_SPI_MINORS); 127 128 129 /* Bit masks for spi_device.mode management. Note that incorrect 130 * settings for some settings can cause *lots* of trouble for other 131 * devices on a shared bus: 132 * 133 * - CS_HIGH ... this device will be active when it shouldn't be 134 * - 3WIRE ... when active, it won't behave as it should 135 * - NO_CS ... there will be no explicit message boundaries; this 136 * is completely incompatible with the shared bus model 137 * - READY ... transfers may proceed when they shouldn't. 138 * 139 * REVISIT should changing those flags be privileged? 140 */ 141 #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ 142 | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ 143 | SPI_NO_CS | SPI_READY) 144 145 struct spidev_data { 146 dev_t devt; 147 spinlock_t spi_lock; 148 struct spi_device *spi; 149 struct list_head device_entry; 150 151 /* buffer is NULL unless this device is open (users > 0) */ 152 struct mutex buf_lock; 153 unsigned users; 154 u8 *buffer; 155 }; 156 157 static LIST_HEAD(device_list); 158 static DEFINE_MUTEX(device_list_lock); 159 160 static unsigned bufsiz = 4096; 161 module_param(bufsiz, uint, S_IRUGO); 162 MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message"); 163 164 /*-------------------------------------------------------------------------*/ 165 166 /* 167 * We can't use the standard synchronous wrappers for file I/O; we 168 * need to protect against async removal of the underlying spi_device. 169 */ 170 171 172 //驱动数据sync发送 173 static void spidev_complete(void *arg) 174 { 175 complete(arg); 176 } 177 178 static ssize_t 179 spidev_sync(struct spidev_data *spidev, struct spi_message *message) 180 { 181 DECLARE_COMPLETION_ONSTACK(done); 182 int status; 183 184 message->complete = spidev_complete; 185 message->context = &done; 186 187 spin_lock_irq(&spidev->spi_lock); 188 if (spidev->spi == NULL) 189 status = -ESHUTDOWN; 190 else 191 status = spi_async(spidev->spi, message); 192 spin_unlock_irq(&spidev->spi_lock); 193 194 if (status == 0) { 195 wait_for_completion(&done); 196 status = message->status; 197 if (status == 0) 198 status = message->actual_length; 199 } 200 return status; 201 } 202 203 204 //驱动写操作 205 static inline ssize_t 206 spidev_sync_write(struct spidev_data *spidev, size_t len) 207 { 208 struct spi_transfer t = { 209 .tx_buf = spidev->buffer, 210 .len = len, 211 }; 212 struct spi_message m; 213 214 spi_message_init(&m); 215 spi_message_add_tail(&t, &m); 216 return spidev_sync(spidev, &m); 217 } 218 219 //驱动读操作 220 static inline ssize_t 221 spidev_sync_read(struct spidev_data *spidev, size_t len) 222 { 223 struct spi_transfer t = { 224 .rx_buf = spidev->buffer, 225 .len = len, 226 }; 227 struct spi_message m; 228 229 spi_message_init(&m); 230 spi_message_add_tail(&t, &m); 231 return spidev_sync(spidev, &m); 232 } 233 234 235 /*-------------------------------------------------------------------------*/ 236 237 238 /* Read-only message with current device setup */ 239 240 //驱动读接口 241 static ssize_t 242 spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) 243 { 244 struct spidev_data *spidev; 245 ssize_t status = 0; 246 247 /* chipselect only toggles at start or end of operation */ 248 if (count > bufsiz) 249 return -EMSGSIZE; 250 251 spidev = filp->private_data; 252 253 mutex_lock(&spidev->buf_lock); 254 status = spidev_sync_read(spidev, count); 255 if (status > 0) { 256 unsigned long missing; 257 258 missing = copy_to_user(buf, spidev->buffer, status); 259 if (missing == status) 260 status = -EFAULT; 261 else 262 status = status - missing; 263 } 264 mutex_unlock(&spidev->buf_lock); 265 266 return status; 267 } 268 269 270 /* Write-only message with current device setup */ 271 272 //驱动写接口 273 static ssize_t 274 spidev_write(struct file *filp, const char __user *buf, 275 size_t count, loff_t *f_pos) 276 { 277 struct spidev_data *spidev; 278 ssize_t status = 0; 279 unsigned long missing; 280 281 /* chipselect only toggles at start or end of operation */ 282 if (count > bufsiz) 283 return -EMSGSIZE; 284 285 spidev = filp->private_data; 286 287 mutex_lock(&spidev->buf_lock); 288 missing = copy_from_user(spidev->buffer, buf, count); 289 if (missing == 0) { 290 status = spidev_sync_write(spidev, count); 291 } else 292 status = -EFAULT; 293 mutex_unlock(&spidev->buf_lock); 294 295 return status; 296 } 297 298 299 //驱动信息队列message 300 static int spidev_message(struct spidev_data *spidev, 301 struct spi_ioc_transfer *u_xfers, unsigned n_xfers) 302 { 303 struct spi_message msg; 304 struct spi_transfer *k_xfers; 305 struct spi_transfer *k_tmp; 306 struct spi_ioc_transfer *u_tmp; 307 unsigned n, total; 308 u8 *buf; 309 int status = -EFAULT; 310 311 spi_message_init(&msg); 312 k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL); 313 if (k_xfers == NULL) 314 return -ENOMEM; 315 316 /* Construct spi_message, copying any tx data to bounce buffer. 317 * We walk the array of user-provided transfers, using each one 318 * to initialize a kernel version of the same transfer. 319 */ 320 buf = spidev->buffer; 321 total = 0; 322 for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; 323 n; 324 n--, k_tmp++, u_tmp++) { 325 k_tmp->len = u_tmp->len; 326 327 total += k_tmp->len; 328 if (total > bufsiz) { 329 status = -EMSGSIZE; 330 goto done; 331 } 332 333 if (u_tmp->rx_buf) { 334 k_tmp->rx_buf = buf; 335 if (!access_ok(VERIFY_WRITE, (u8 __user *) 336 (uintptr_t) u_tmp->rx_buf, 337 u_tmp->len)) 338 goto done; 339 } 340 if (u_tmp->tx_buf) { 341 k_tmp->tx_buf = buf; 342 if (copy_from_user(buf, (const u8 __user *) 343 (uintptr_t) u_tmp->tx_buf, 344 u_tmp->len)) 345 goto done; 346 } 347 buf += k_tmp->len; 348 349 k_tmp->cs_change = !!u_tmp->cs_change; 350 k_tmp->bits_per_word = u_tmp->bits_per_word; 351 k_tmp->delay_usecs = u_tmp->delay_usecs; 352 k_tmp->speed_hz = u_tmp->speed_hz; 353 #ifdef VERBOSE 354 dev_dbg(&spidev->spi->dev, 355 " xfer len %zd %s%s%s%dbits %u usec %uHz\n", 356 u_tmp->len, 357 u_tmp->rx_buf ? "rx " : "", 358 u_tmp->tx_buf ? "tx " : "", 359 u_tmp->cs_change ? "cs " : "", 360 u_tmp->bits_per_word ? : spidev->spi->bits_per_word, 361 u_tmp->delay_usecs, 362 u_tmp->speed_hz ? : spidev->spi->max_speed_hz); 363 #endif 364 spi_message_add_tail(k_tmp, &msg); 365 } 366 367 status = spidev_sync(spidev, &msg); 368 if (status < 0) 369 goto done; 370 371 /* copy any rx data out of bounce buffer */ 372 buf = spidev->buffer; 373 for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) { 374 if (u_tmp->rx_buf) { 375 if (__copy_to_user((u8 __user *) 376 (uintptr_t) u_tmp->rx_buf, buf, 377 u_tmp->len)) { 378 status = -EFAULT; 379 goto done; 380 } 381 } 382 buf += u_tmp->len; 383 } 384 status = total; 385 386 done: 387 kfree(k_xfers); 388 return status; 389 } 390 391 #if 0 392 393 //驱动ioctl接口 394 static long 395 spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 396 { 397 int err = 0; 398 int retval = 0; 399 struct spidev_data *spidev; 400 struct spi_device *spi; 401 u32 tmp; 402 unsigned n_ioc; 403 struct spi_ioc_transfer *ioc; 404 405 /* Check type and command number */ 406 if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC) 407 return -ENOTTY; 408 409 /* Check access direction once here; don't repeat below. 410 * IOC_DIR is from the user perspective, while access_ok is 411 * from the kernel perspective; so they look reversed. 412 */ 413 if (_IOC_DIR(cmd) & _IOC_READ) 414 err = !access_ok(VERIFY_WRITE, 415 (void __user *)arg, _IOC_SIZE(cmd)); 416 if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE) 417 err = !access_ok(VERIFY_READ, 418 (void __user *)arg, _IOC_SIZE(cmd)); 419 if (err) 420 return -EFAULT; 421 422 /* guard against device removal before, or while, 423 * we issue this ioctl. 424 */ 425 spidev = filp->private_data; 426 spin_lock_irq(&spidev->spi_lock); 427 spi = spi_dev_get(spidev->spi); 428 spin_unlock_irq(&spidev->spi_lock); 429 430 if (spi == NULL) 431 return -ESHUTDOWN; 432 433 /* use the buffer lock here for triple duty: 434 * - prevent I/O (from us) so calling spi_setup() is safe; 435 * - prevent concurrent SPI_IOC_WR_* from morphing 436 * data fields while SPI_IOC_RD_* reads them; 437 * - SPI_IOC_MESSAGE needs the buffer locked "normally". 438 */ 439 mutex_lock(&spidev->buf_lock); 440 441 switch (cmd) { 442 /* read requests */ 443 case SPI_IOC_RD_MODE: 444 retval = __put_user(spi->mode & SPI_MODE_MASK, 445 (__u8 __user *)arg); 446 break; 447 case SPI_IOC_RD_LSB_FIRST: 448 retval = __put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0, 449 (__u8 __user *)arg); 450 break; 451 case SPI_IOC_RD_BITS_PER_WORD: 452 retval = __put_user(spi->bits_per_word, (__u8 __user *)arg); 453 break; 454 case SPI_IOC_RD_MAX_SPEED_HZ: 455 retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg); 456 break; 457 458 /* write requests */ 459 case SPI_IOC_WR_MODE: 460 retval = __get_user(tmp, (u8 __user *)arg); 461 if (retval == 0) { 462 u8 save = spi->mode; 463 464 if (tmp & ~SPI_MODE_MASK) { 465 retval = -EINVAL; 466 break; 467 } 468 469 tmp |= spi->mode & ~SPI_MODE_MASK; 470 spi->mode = (u8)tmp; 471 retval = spi_setup(spi); 472 if (retval < 0) 473 spi->mode = save; 474 else 475 dev_dbg(&spi->dev, "spi mode %02x\n", tmp); 476 } 477 break; 478 case SPI_IOC_WR_LSB_FIRST: 479 retval = __get_user(tmp, (__u8 __user *)arg); 480 if (retval == 0) { 481 u8 save = spi->mode; 482 483 if (tmp) 484 spi->mode |= SPI_LSB_FIRST; 485 else 486 spi->mode &= ~SPI_LSB_FIRST; 487 retval = spi_setup(spi); 488 if (retval < 0) 489 spi->mode = save; 490 else 491 dev_dbg(&spi->dev, "%csb first\n", 492 tmp ? 'l' : 'm'); 493 } 494 break; 495 case SPI_IOC_WR_BITS_PER_WORD: 496 retval = __get_user(tmp, (__u8 __user *)arg); 497 if (retval == 0) { 498 u8 save = spi->bits_per_word; 499 500 spi->bits_per_word = tmp; 501 retval = spi_setup(spi); 502 if (retval < 0) 503 spi->bits_per_word = save; 504 else 505 dev_dbg(&spi->dev, "%d bits per word\n", tmp); 506 } 507 break; 508 case SPI_IOC_WR_MAX_SPEED_HZ: 509 retval = __get_user(tmp, (__u32 __user *)arg); 510 if (retval == 0) { 511 u32 save = spi->max_speed_hz; 512 513 spi->max_speed_hz = tmp; 514 retval = spi_setup(spi); 515 if (retval < 0) 516 spi->max_speed_hz = save; 517 else 518 dev_dbg(&spi->dev, "%d Hz (max)\n", tmp); 519 } 520 break; 521 522 default: 523 /* segmented and/or full-duplex I/O request */ 524 if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) 525 || _IOC_DIR(cmd) != _IOC_WRITE) { 526 retval = -ENOTTY; 527 break; 528 } 529 530 tmp = _IOC_SIZE(cmd); 531 if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { 532 retval = -EINVAL; 533 break; 534 } 535 n_ioc = tmp / sizeof(struct spi_ioc_transfer); 536 if (n_ioc == 0) 537 break; 538 539 /* copy into scratch area */ 540 ioc = kmalloc(tmp, GFP_KERNEL); 541 if (!ioc) { 542 retval = -ENOMEM; 543 break; 544 } 545 if (__copy_from_user(ioc, (void __user *)arg, tmp)) { 546 kfree(ioc); 547 retval = -EFAULT; 548 break; 549 } 550 551 /* translate to spi_message, execute */ 552 retval = spidev_message(spidev, ioc, n_ioc); 553 kfree(ioc); 554 break; 555 } 556 557 mutex_unlock(&spidev->buf_lock); 558 spi_dev_put(spi); 559 return retval; 560 } 561 562 #endif 563 564 #ifdef CONFIG_COMPAT 565 //static long 566 //spidev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 567 //{ 568 // return spidev_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); 569 //} 570 #else 571 #define spidev_compat_ioctl NULL 572 #endif /* CONFIG_COMPAT */ 573 574 575 //驱动open接口 576 static int spidev_open(struct inode *inode, struct file *filp) 577 { 578 struct spidev_data *spidev; 579 int status = -ENXIO; 580 581 mutex_lock(&device_list_lock); 582 583 list_for_each_entry(spidev, &device_list, device_entry) { 584 if (spidev->devt == inode->i_rdev) { 585 status = 0; 586 break; 587 } 588 } 589 if (status == 0) { 590 if (!spidev->buffer) { 591 spidev->buffer = kmalloc(bufsiz, GFP_KERNEL); 592 if (!spidev->buffer) { 593 dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); 594 status = -ENOMEM; 595 } 596 } 597 if (status == 0) { 598 spidev->users++; 599 filp->private_data = spidev; 600 nonseekable_open(inode, filp); 601 } 602 } else 603 pr_debug("spidev: nothing for minor %d\n", iminor(inode)); 604 605 mutex_unlock(&device_list_lock); 606 return status; 607 } 608 609 610 // 驱动release接口 611 static int spidev_release(struct inode *inode, struct file *filp) 612 { 613 struct spidev_data *spidev; 614 int status = 0; 615 616 mutex_lock(&device_list_lock); 617 spidev = filp->private_data; 618 filp->private_data = NULL; 619 620 /* last close? */ 621 spidev->users--; 622 if (!spidev->users) { 623 int dofree; 624 625 kfree(spidev->buffer); 626 spidev->buffer = NULL; 627 628 /* ... after we unbound from the underlying device? */ 629 spin_lock_irq(&spidev->spi_lock); 630 dofree = (spidev->spi == NULL); 631 spin_unlock_irq(&spidev->spi_lock); 632 633 if (dofree) 634 kfree(spidev); 635 } 636 mutex_unlock(&device_list_lock); 637 638 return status; 639 } 640 641 642 /*-------------------------------------------------------------------------*/ 643 644 /* The main reason to have this class is to make mdev/udev create the 645 * /dev/spidevB.C character device nodes exposing our userspace API. 646 * It also simplifies memory management. 647 */ 648 649 static struct class *spidev_class; 650 651 /*-------------------------------------------------------------------------*/ 652 653 654 655 /******************************* device inint ***********************************/ 656 657 658 659 /*****封装一个写操作*****/ 660 static inline ssize_t mysync_write(struct spidev_data *spidev, unsigned char addr, unsigned char tx_buff) 661 { 662 663 u8 tx[2] ; 664 665 tx[0] = addr ; 666 tx[1] =tx_buff; 667 668 struct spi_transfer t = { 669 .tx_buf = tx, 670 .len = 2, 671 672 }; 673 674 struct spi_message m; 675 676 spi_message_init(&m); 677 spi_message_add_tail(&t, &m); 678 679 return spidev_sync(spidev, &m); 680 681 } 682 683 684 685 /*****封装一个读操作*****/ 686 static inline ssize_t mysync_read(struct spidev_data *spidev, unsigned char addr) 687 { 688 689 // 先发一个地址 读模式 690 u8 tx[2] ; 691 tx[0] = addr | 0x80; // 先写寄存器地址 读模式 692 tx[1] = 0x88; // 再写数据 693 u8 rx[2] = {0}; // 再读出数据 694 695 struct spi_transfer t[2] = { 696 [0] = { 697 .tx_buf = tx, 698 .rx_buf = rx, 699 .len = 2, 700 }, 701 702 [1] = { 703 .rx_buf = rx, 704 .len = 2, 705 }, 706 }; 707 708 struct spi_message m; 709 spi_message_init(&m); 710 spi_message_add_tail(&t, &m); 711 spidev_sync(spidev, &m); 712 713 // printk("read = %0x\n",rx[0]); 714 // printk("read = %0x\n",rx[1]); 715 716 return rx[1]; 717 718 } 719 720 721 /* 722 723 static ssize_t 724 spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) 725 { 726 727 728 729 } 730 731 */ 732 733 734 /*****自己封装一个ioctl接口*****/ 735 static long dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 736 { 737 738 printk("kernel ioctl success ! \n"); 739 740 struct spidev_data *spidev; 741 struct spi_device *spi; 742 743 spidev = filp->private_data; 744 spin_lock_irq(&spidev->spi_lock); 745 spi = spi_dev_get(spidev->spi); 746 spin_unlock_irq(&spidev->spi_lock); 747 748 // struct spidev_data *spidev = NULL; 749 int res = 0; 750 union mpu6500_data data = {{0}}; 751 switch(cmd){ 752 case GET_ACCEL: 753 data.accel.x = mysync_read(spidev,ACCEL_XOUT_L); 754 udelay(1); 755 data.accel.x|= mysync_read(spidev,ACCEL_XOUT_H)<<8; 756 udelay(1); 757 data.accel.y = mysync_read(spidev,ACCEL_YOUT_L); 758 udelay(1); 759 data.accel.y|= mysync_read(spidev,ACCEL_YOUT_H)<<8; 760 udelay(1); 761 data.accel.z = mysync_read(spidev,ACCEL_ZOUT_L); 762 udelay(1); 763 data.accel.z|= mysync_read(spidev,ACCEL_ZOUT_H)<<8; 764 udelay(1); 765 break; 766 case GET_GYRO: 767 data.gyro.x = mysync_read(spidev,GYRO_XOUT_L); 768 udelay(1); 769 data.gyro.x|= mysync_read(spidev,GYRO_XOUT_H)<<8; 770 udelay(1); 771 data.gyro.y = mysync_read(spidev,GYRO_YOUT_L); 772 udelay(1); 773 data.gyro.y|= mysync_read(spidev,GYRO_YOUT_H)<<8; 774 udelay(1); 775 data.gyro.z = mysync_read(spidev,GYRO_ZOUT_L); 776 udelay(1); 777 data.gyro.z|= mysync_read(spidev,GYRO_ZOUT_H)<<8; 778 udelay(1); 779 printk("gyro:x %d, y:%d, z:%d\n",data.gyro.x,data.gyro.y,data.gyro.z); 780 break; 781 case GET_TEMP: 782 data.temp = mysync_read(spidev,TEMP_OUT_L); 783 udelay(1); 784 data.temp|= mysync_read(spidev,TEMP_OUT_H)<<8; 785 udelay(1); 786 printk("temp: %d\n",data.temp); 787 break; 788 default: 789 printk(KERN_INFO "invalid cmd"); 790 break; 791 } 792 printk("acc:x %d, y:%d, z:%d\n",data.accel.x,data.accel.y,data.accel.z); 793 794 res = copy_to_user((void *)arg,&data,sizeof(data)); 795 796 return sizeof(data); 797 } 798 799 800 //驱动实现FOPS 801 static const struct file_operations spidev_fops = { 802 .owner = THIS_MODULE, 803 /* REVISIT switch to aio primitives, so that userspace 804 * gets more complete API coverage. It'll simplify things 805 * too, except for the locking. 806 */ 807 .write = spidev_write, 808 .read = spi_read, 809 810 // .read = spidev_read, 811 // .unlocked_ioctl = spidev_ioctl, 812 813 .unlocked_ioctl = dev_ioctl, 814 815 // .compat_ioctl = spidev_compat_ioctl, 816 .open = spidev_open, 817 .release = spidev_release, 818 .llseek = no_llseek, 819 }; 820 821 822 /*****硬件初始化*****/ 823 void mpu6500_init(struct spidev_data *spidev) 824 { 825 826 udelay(1); 827 828 // printk("kernel mpu6500_init success ! \n"); 829 mysync_write(spidev,PWR_MGMT_1,0x00); //电源管理,解除休眠 830 udelay(1); 831 832 // printk("kernel dianyuan success ! \n"); 833 mysync_write(spidev,SMPLRT_DIV,0x07); //设置陀螺仪采样率 834 udelay(1); 835 836 // printk("kernel caiyang success ! \n"); 837 mysync_write(spidev,CONFIG,0x06); //设置低通滤波频率 838 udelay(1); 839 840 // printk("kernel lvbo success ! \n"); 841 mysync_write(spidev,GYRO_CONFIG,0x18); //设置陀螺仪自检 842 udelay(1); 843 844 // printk("kernel zijian success ! \n"); 845 mysync_write(spidev,ACCEL_CONFIG,0x00); //设置加速计自检 846 udelay(1); 847 848 // printk("kernel jiasu success ! \n"); 849 850 851 mysync_read(spidev,ACCEL_XOUT_L); 852 mysync_read(spidev,ACCEL_XOUT_H); 853 854 855 return 0; 856 } 857 858 859 /******************************* device inint ***********************************/ 860 861 862 static int spidev_probe(struct spi_device *spi) 863 { 864 865 printk("probe ok !\n"); 866 867 struct spidev_data *spidev; 868 int status; 869 unsigned long minor; 870 871 /* Allocate driver data */ 872 spidev = kzalloc(sizeof(*spidev), GFP_KERNEL); 873 if (!spidev) 874 return -ENOMEM; 875 876 /* Initialize the driver data */ 877 878 879 spidev->spi = spi; 880 spin_lock_init(&spidev->spi_lock); 881 mutex_init(&spidev->buf_lock); 882 883 INIT_LIST_HEAD(&spidev->device_entry); 884 885 /* If we can allocate a minor number, hook up this device. 886 * Reusing minors is fine so long as udev or mdev is working. 887 */ 888 mutex_lock(&device_list_lock); 889 minor = find_first_zero_bit(minors, N_SPI_MINORS); 890 if (minor < N_SPI_MINORS) { 891 struct device *dev; 892 893 spidev->devt = MKDEV(SPIDEV_MAJOR, minor); 894 dev = device_create(spidev_class, &spi->dev, spidev->devt, 895 spidev, "spidev%d.%d", 896 spi->master->bus_num, spi->chip_select); 897 status = IS_ERR(dev) ? PTR_ERR(dev) : 0; 898 } else { 899 dev_dbg(&spi->dev, "no minor number available!\n"); 900 status = -ENODEV; 901 } 902 if (status == 0) { 903 set_bit(minor, minors); 904 list_add(&spidev->device_entry, &device_list); 905 } 906 mutex_unlock(&device_list_lock); 907 908 if (status == 0) 909 spi_set_drvdata(spi, spidev); 910 else 911 kfree(spidev); 912 913 914 /*****硬件初始化*****/ 915 mpu6500_init(spidev); 916 917 918 return status; 919 } 920 921 static int spidev_remove(struct spi_device *spi) 922 { 923 struct spidev_data *spidev = spi_get_drvdata(spi); 924 925 /* make sure ops on existing fds can abort cleanly */ 926 spin_lock_irq(&spidev->spi_lock); 927 spidev->spi = NULL; 928 spi_set_drvdata(spi, NULL); 929 spin_unlock_irq(&spidev->spi_lock); 930 931 /* prevent new opens */ 932 mutex_lock(&device_list_lock); 933 list_del(&spidev->device_entry); 934 device_destroy(spidev_class, spidev->devt); 935 clear_bit(MINOR(spidev->devt), minors); 936 if (spidev->users == 0) 937 kfree(spidev); 938 mutex_unlock(&device_list_lock); 939 940 printk("remove ok !\n"); 941 942 return 0; 943 } 944 945 static struct spi_driver spidev_spi_driver = { 946 .driver = { 947 .name = "spidev", 948 .owner = THIS_MODULE, 949 }, 950 .probe = spidev_probe, 951 .remove = spidev_remove, 952 953 /* NOTE: suspend/resume methods are not necessary here. 954 * We don't do anything except pass the requests to/from 955 * the underlying controller. The refrigerator handles 956 * most issues; the controller driver handles the rest. 957 */ 958 }; 959 960 /*-------------------------------------------------------------------------*/ 961 962 static int __init spidev_init(void) 963 { 964 965 printk("init ok !\n"); 966 967 int status; 968 969 /* Claim our 256 reserved device numbers. Then register a class 970 * that will key udev/mdev to add/remove /dev nodes. Last, register 971 * the driver which manages those device numbers. 972 */ 973 BUILD_BUG_ON(N_SPI_MINORS > 256); 974 status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops); 975 if (status < 0) 976 return status; 977 978 spidev_class = class_create(THIS_MODULE, "spidev"); 979 if (IS_ERR(spidev_class)) { 980 unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); 981 return PTR_ERR(spidev_class); 982 } 983 984 status = spi_register_driver(&spidev_spi_driver); 985 if (status < 0) { 986 class_destroy(spidev_class); 987 unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); 988 } 989 return status; 990 } 991 module_init(spidev_init); 992 993 static void __exit spidev_exit(void) 994 { 995 996 printk("exit ok !\n"); 997 998 spi_unregister_driver(&spidev_spi_driver); 999 class_destroy(spidev_class); 1000 unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); 1001 } 1002 module_exit(spidev_exit); 1003 1004 MODULE_AUTHOR("Andrea Paterniani, "); 1005 MODULE_DESCRIPTION("User mode SPI device interface"); 1006 MODULE_LICENSE("GPL"); 1007 MODULE_ALIAS("spi:spidev");
笔记