Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.4-rc5 112 lines 2.6 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved. 4 * 5 * Author: Wu Guoxing <b39297@freescale.com> 6 */ 7 8#include <linux/kernel.h> 9#include <linux/init.h> 10#include <linux/slab.h> 11#include <linux/i2c.h> 12#include <linux/gpio/driver.h> 13 14#define GPIO_GROUP_NUM 2 15#define GPIO_NUM_PER_GROUP 8 16#define GPIO_NUM (GPIO_GROUP_NUM*GPIO_NUM_PER_GROUP) 17 18struct mc9s08dz60 { 19 struct i2c_client *client; 20 struct gpio_chip chip; 21}; 22 23static void mc9s_gpio_to_reg_and_bit(int offset, u8 *reg, u8 *bit) 24{ 25 *reg = 0x20 + offset / GPIO_NUM_PER_GROUP; 26 *bit = offset % GPIO_NUM_PER_GROUP; 27} 28 29static int mc9s08dz60_get_value(struct gpio_chip *gc, unsigned offset) 30{ 31 u8 reg, bit; 32 s32 value; 33 struct mc9s08dz60 *mc9s = gpiochip_get_data(gc); 34 35 mc9s_gpio_to_reg_and_bit(offset, &reg, &bit); 36 value = i2c_smbus_read_byte_data(mc9s->client, reg); 37 38 return (value >= 0) ? (value >> bit) & 0x1 : 0; 39} 40 41static int mc9s08dz60_set(struct mc9s08dz60 *mc9s, unsigned offset, int val) 42{ 43 u8 reg, bit; 44 s32 value; 45 46 mc9s_gpio_to_reg_and_bit(offset, &reg, &bit); 47 value = i2c_smbus_read_byte_data(mc9s->client, reg); 48 if (value >= 0) { 49 if (val) 50 value |= 1 << bit; 51 else 52 value &= ~(1 << bit); 53 54 return i2c_smbus_write_byte_data(mc9s->client, reg, value); 55 } else 56 return value; 57 58} 59 60 61static void mc9s08dz60_set_value(struct gpio_chip *gc, unsigned offset, int val) 62{ 63 struct mc9s08dz60 *mc9s = gpiochip_get_data(gc); 64 65 mc9s08dz60_set(mc9s, offset, val); 66} 67 68static int mc9s08dz60_direction_output(struct gpio_chip *gc, 69 unsigned offset, int val) 70{ 71 struct mc9s08dz60 *mc9s = gpiochip_get_data(gc); 72 73 return mc9s08dz60_set(mc9s, offset, val); 74} 75 76static int mc9s08dz60_probe(struct i2c_client *client, 77 const struct i2c_device_id *id) 78{ 79 struct mc9s08dz60 *mc9s; 80 81 mc9s = devm_kzalloc(&client->dev, sizeof(*mc9s), GFP_KERNEL); 82 if (!mc9s) 83 return -ENOMEM; 84 85 mc9s->chip.label = client->name; 86 mc9s->chip.base = -1; 87 mc9s->chip.parent = &client->dev; 88 mc9s->chip.owner = THIS_MODULE; 89 mc9s->chip.ngpio = GPIO_NUM; 90 mc9s->chip.can_sleep = true; 91 mc9s->chip.get = mc9s08dz60_get_value; 92 mc9s->chip.set = mc9s08dz60_set_value; 93 mc9s->chip.direction_output = mc9s08dz60_direction_output; 94 mc9s->client = client; 95 i2c_set_clientdata(client, mc9s); 96 97 return devm_gpiochip_add_data(&client->dev, &mc9s->chip, mc9s); 98} 99 100static const struct i2c_device_id mc9s08dz60_id[] = { 101 {"mc9s08dz60", 0}, 102 {}, 103}; 104 105static struct i2c_driver mc9s08dz60_i2c_driver = { 106 .driver = { 107 .name = "mc9s08dz60", 108 }, 109 .probe = mc9s08dz60_probe, 110 .id_table = mc9s08dz60_id, 111}; 112builtin_i2c_driver(mc9s08dz60_i2c_driver);