Blame view
drivers/mfd/tps65912-spi.c
3.22 KB
36e52873c mfd: tps65912: Ad... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
/* * tps65912-spi.c -- SPI access for TI TPS65912x PMIC * * Copyright 2011 Texas Instruments Inc. * * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This driver is based on wm8350 implementation. */ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/gpio.h> #include <linux/spi/spi.h> #include <linux/mfd/core.h> #include <linux/mfd/tps65912.h> static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr, int bytes, void *src) { struct spi_device *spi = tps65912->control_data; u8 *data = (u8 *) src; int ret; /* bit 23 is the read/write bit */ unsigned long spi_data = 1 << 23 | addr << 15 | *data; struct spi_transfer xfer; struct spi_message msg; u32 tx_buf, rx_buf; tx_buf = spi_data; rx_buf = 0; xfer.tx_buf = &tx_buf; xfer.rx_buf = NULL; xfer.len = sizeof(unsigned long); xfer.bits_per_word = 24; spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(spi, &msg); return ret; } static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr, int bytes, void *dest) { struct spi_device *spi = tps65912->control_data; /* bit 23 is the read/write bit */ unsigned long spi_data = 0 << 23 | addr << 15; struct spi_transfer xfer; struct spi_message msg; int ret; u8 *data = (u8 *) dest; u32 tx_buf, rx_buf; tx_buf = spi_data; rx_buf = 0; xfer.tx_buf = &tx_buf; xfer.rx_buf = &rx_buf; xfer.len = sizeof(unsigned long); xfer.bits_per_word = 24; spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); if (spi == NULL) return 0; ret = spi_sync(spi, &msg); if (ret == 0) *data = (u8) (rx_buf & 0xFF); return ret; } static int __devinit tps65912_spi_probe(struct spi_device *spi) { struct tps65912 *tps65912; tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL); if (tps65912 == NULL) return -ENOMEM; tps65912->dev = &spi->dev; tps65912->control_data = spi; tps65912->read = tps65912_spi_read; tps65912->write = tps65912_spi_write; spi_set_drvdata(spi, tps65912); return tps65912_device_init(tps65912); } static int __devexit tps65912_spi_remove(struct spi_device *spi) { struct tps65912 *tps65912 = spi_get_drvdata(spi); tps65912_device_exit(tps65912); return 0; } static struct spi_driver tps65912_spi_driver = { .driver = { .name = "tps65912", |
36e52873c mfd: tps65912: Ad... |
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
.owner = THIS_MODULE, }, .probe = tps65912_spi_probe, .remove = __devexit_p(tps65912_spi_remove), }; static int __init tps65912_spi_init(void) { int ret; ret = spi_register_driver(&tps65912_spi_driver); if (ret != 0) pr_err("Failed to register TPS65912 SPI driver: %d ", ret); return 0; } /* init early so consumer devices can complete system boot */ subsys_initcall(tps65912_spi_init); static void __exit tps65912_spi_exit(void) { spi_unregister_driver(&tps65912_spi_driver); } module_exit(tps65912_spi_exit); MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd"); MODULE_LICENSE("GPL"); |