PageRenderTime 43ms CodeModel.GetById 33ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/media/video/bt8xx/bttv-gpio.c

https://gitlab.com/TeamCarbonXtreme/android_kernel_samsung_msm7x27
C | 187 lines | 119 code | 30 blank | 38 comment | 7 complexity | cacd4d168a367d53138d6e2124c97904 MD5 | raw file
  1/*
  2
  3    bttv-gpio.c  --  gpio sub drivers
  4
  5    sysfs-based sub driver interface for bttv
  6    mainly intented for gpio access
  7
  8
  9    Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
 10			   & Marcus Metzler (mocm@thp.uni-koeln.de)
 11    (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
 12
 13    This program is free software; you can redistribute it and/or modify
 14    it under the terms of the GNU General Public License as published by
 15    the Free Software Foundation; either version 2 of the License, or
 16    (at your option) any later version.
 17
 18    This program is distributed in the hope that it will be useful,
 19    but WITHOUT ANY WARRANTY; without even the implied warranty of
 20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21    GNU General Public License for more details.
 22
 23    You should have received a copy of the GNU General Public License
 24    along with this program; if not, write to the Free Software
 25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 26
 27*/
 28
 29#include <linux/module.h>
 30#include <linux/init.h>
 31#include <linux/delay.h>
 32#include <linux/device.h>
 33#include <linux/slab.h>
 34#include <asm/io.h>
 35
 36#include "bttvp.h"
 37
 38/* ----------------------------------------------------------------------- */
 39/* internal: the bttv "bus"                                                */
 40
 41static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
 42{
 43	struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
 44	int len = strlen(sub->wanted);
 45
 46	if (0 == strncmp(dev_name(dev), sub->wanted, len))
 47		return 1;
 48	return 0;
 49}
 50
 51static int bttv_sub_probe(struct device *dev)
 52{
 53	struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
 54	struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
 55
 56	return sub->probe ? sub->probe(sdev) : -ENODEV;
 57}
 58
 59static int bttv_sub_remove(struct device *dev)
 60{
 61	struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
 62	struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
 63
 64	if (sub->remove)
 65		sub->remove(sdev);
 66	return 0;
 67}
 68
 69struct bus_type bttv_sub_bus_type = {
 70	.name   = "bttv-sub",
 71	.match  = &bttv_sub_bus_match,
 72	.probe  = bttv_sub_probe,
 73	.remove = bttv_sub_remove,
 74};
 75
 76static void release_sub_device(struct device *dev)
 77{
 78	struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
 79	kfree(sub);
 80}
 81
 82int bttv_sub_add_device(struct bttv_core *core, char *name)
 83{
 84	struct bttv_sub_device *sub;
 85	int err;
 86
 87	sub = kzalloc(sizeof(*sub),GFP_KERNEL);
 88	if (NULL == sub)
 89		return -ENOMEM;
 90
 91	sub->core        = core;
 92	sub->dev.parent  = &core->pci->dev;
 93	sub->dev.bus     = &bttv_sub_bus_type;
 94	sub->dev.release = release_sub_device;
 95	dev_set_name(&sub->dev, "%s%d", name, core->nr);
 96
 97	err = device_register(&sub->dev);
 98	if (0 != err) {
 99		kfree(sub);
100		return err;
101	}
102	printk("bttv%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev));
103	list_add_tail(&sub->list,&core->subs);
104	return 0;
105}
106
107int bttv_sub_del_devices(struct bttv_core *core)
108{
109	struct bttv_sub_device *sub, *save;
110
111	list_for_each_entry_safe(sub, save, &core->subs, list) {
112		list_del(&sub->list);
113		device_unregister(&sub->dev);
114	}
115	return 0;
116}
117
118/* ----------------------------------------------------------------------- */
119/* external: sub-driver register/unregister                                */
120
121int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
122{
123	sub->drv.bus = &bttv_sub_bus_type;
124	snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
125	return driver_register(&sub->drv);
126}
127EXPORT_SYMBOL(bttv_sub_register);
128
129int bttv_sub_unregister(struct bttv_sub_driver *sub)
130{
131	driver_unregister(&sub->drv);
132	return 0;
133}
134EXPORT_SYMBOL(bttv_sub_unregister);
135
136/* ----------------------------------------------------------------------- */
137/* external: gpio access functions                                         */
138
139void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
140{
141	struct bttv *btv = container_of(core, struct bttv, c);
142	unsigned long flags;
143	u32 data;
144
145	spin_lock_irqsave(&btv->gpio_lock,flags);
146	data = btread(BT848_GPIO_OUT_EN);
147	data = data & ~mask;
148	data = data | (mask & outbits);
149	btwrite(data,BT848_GPIO_OUT_EN);
150	spin_unlock_irqrestore(&btv->gpio_lock,flags);
151}
152
153u32 bttv_gpio_read(struct bttv_core *core)
154{
155	struct bttv *btv = container_of(core, struct bttv, c);
156	u32 value;
157
158	value = btread(BT848_GPIO_DATA);
159	return value;
160}
161
162void bttv_gpio_write(struct bttv_core *core, u32 value)
163{
164	struct bttv *btv = container_of(core, struct bttv, c);
165
166	btwrite(value,BT848_GPIO_DATA);
167}
168
169void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
170{
171	struct bttv *btv = container_of(core, struct bttv, c);
172	unsigned long flags;
173	u32 data;
174
175	spin_lock_irqsave(&btv->gpio_lock,flags);
176	data = btread(BT848_GPIO_DATA);
177	data = data & ~mask;
178	data = data | (mask & bits);
179	btwrite(data,BT848_GPIO_DATA);
180	spin_unlock_irqrestore(&btv->gpio_lock,flags);
181}
182
183/*
184 * Local variables:
185 * c-basic-offset: 8
186 * End:
187 */