⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locomo.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 *	up the registered devices. */static struct platform_driver locomo_device_driver = {	.probe		= locomo_probe,	.remove		= locomo_remove,#ifdef CONFIG_PM	.suspend	= locomo_suspend,	.resume		= locomo_resume,#endif	.driver		= {		.name	= "locomo",	},};/* *	Get the parent device driver (us) structure *	from a child function device */static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev){	return (struct locomo *)dev_get_drvdata(ldev->dev.parent);}void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir){	struct locomo *lchip = dev_get_drvdata(dev);	unsigned long flags;	unsigned int r;	if (!lchip)		return;	spin_lock_irqsave(&lchip->lock, flags);	r = locomo_readl(lchip->base + LOCOMO_GPD);	r &= ~bits;	locomo_writel(r, lchip->base + LOCOMO_GPD);	r = locomo_readl(lchip->base + LOCOMO_GPE);	if (dir)		r |= bits;	else		r &= ~bits;	locomo_writel(r, lchip->base + LOCOMO_GPE);	spin_unlock_irqrestore(&lchip->lock, flags);}int locomo_gpio_read_level(struct device *dev, unsigned int bits){	struct locomo *lchip = dev_get_drvdata(dev);	unsigned long flags;	unsigned int ret;	if (!lchip)		return -ENODEV;	spin_lock_irqsave(&lchip->lock, flags);	ret = locomo_readl(lchip->base + LOCOMO_GPL);	spin_unlock_irqrestore(&lchip->lock, flags);	ret &= bits;	return ret;}int locomo_gpio_read_output(struct device *dev, unsigned int bits){	struct locomo *lchip = dev_get_drvdata(dev);	unsigned long flags;	unsigned int ret;	if (!lchip)		return -ENODEV;	spin_lock_irqsave(&lchip->lock, flags);	ret = locomo_readl(lchip->base + LOCOMO_GPO);	spin_unlock_irqrestore(&lchip->lock, flags);	ret &= bits;	return ret;}void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set){	struct locomo *lchip = dev_get_drvdata(dev);	unsigned long flags;	unsigned int r;	if (!lchip)		return;	spin_lock_irqsave(&lchip->lock, flags);	r = locomo_readl(lchip->base + LOCOMO_GPO);	if (set)		r |= bits;	else		r &= ~bits;	locomo_writel(r, lchip->base + LOCOMO_GPO);	spin_unlock_irqrestore(&lchip->lock, flags);}static void locomo_m62332_sendbit(void *mapbase, int bit){	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SCLOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SCLOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */	if (bit & 1) {		r = locomo_readl(mapbase + LOCOMO_DAC);		r |=  LOCOMO_DAC_SDAOEB;		locomo_writel(r, mapbase + LOCOMO_DAC);		udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	} else {		r = locomo_readl(mapbase + LOCOMO_DAC);		r &=  ~(LOCOMO_DAC_SDAOEB);		locomo_writel(r, mapbase + LOCOMO_DAC);		udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	}	udelay(DAC_DATA_SETUP_TIME);	/* 250 nsec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SCLOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_HIGH_HOLD_TIME);	/*  4.0 usec */}void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel){	struct locomo *lchip = locomo_chip_driver(ldev);	int i;	unsigned char data;	unsigned int r;	void *mapbase = lchip->base;	unsigned long flags;	spin_lock_irqsave(&lchip->lock, flags);	/* Start */	udelay(DAC_BUS_FREE_TIME);	/* 5.0 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.0 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SDAOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_START_HOLD_TIME);	/* 5.0 usec */	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */	/* Send slave address and W bit (LSB is W bit) */	data = (M62332_SLAVE_ADDR << 1) | M62332_W_BIT;	for (i = 1; i <= 8; i++) {		locomo_m62332_sendbit(mapbase, data >> (8 - i));	}	/* Check A bit */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SCLOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SDAOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SCLOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */		printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");		return;	}	/* Send Sub address (LSB is channel select) */	/*    channel = 0 : ch1 select              */	/*            = 1 : ch2 select              */	data = M62332_SUB_ADDR + channel;	for (i = 1; i <= 8; i++) {		locomo_m62332_sendbit(mapbase, data >> (8 - i));	}	/* Check A bit */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SCLOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SDAOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SCLOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */		printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");		return;	}	/* Send DAC data */	for (i = 1; i <= 8; i++) {		locomo_m62332_sendbit(mapbase, dac_data >> (8 - i));	}	/* Check A bit */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SCLOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SDAOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SCLOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */		printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");		return;	}	/* stop */	r = locomo_readl(mapbase + LOCOMO_DAC);	r &=  ~(LOCOMO_DAC_SCLOEB);	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SCLOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SDAOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */	r = locomo_readl(mapbase + LOCOMO_DAC);	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;	locomo_writel(r, mapbase + LOCOMO_DAC);	udelay(DAC_LOW_SETUP_TIME);	/* 1000 nsec */	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */	spin_unlock_irqrestore(&lchip->lock, flags);}/* *	Frontlight control */static struct locomo *locomo_chip_driver(struct locomo_dev *ldev);void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf){	unsigned long flags;	struct locomo *lchip = locomo_chip_driver(dev);	if (vr)		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1);	else		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0);	spin_lock_irqsave(&lchip->lock, flags);	locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);	udelay(100);	locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);	locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);	spin_unlock_irqrestore(&lchip->lock, flags);}/* *	LoCoMo "Register Access Bus." * *	We model this as a regular bus type, and hang devices directly *	off this. */static int locomo_match(struct device *_dev, struct device_driver *_drv){	struct locomo_dev *dev = LOCOMO_DEV(_dev);	struct locomo_driver *drv = LOCOMO_DRV(_drv);	return dev->devid == drv->devid;}static int locomo_bus_suspend(struct device *dev, pm_message_t state){	struct locomo_dev *ldev = LOCOMO_DEV(dev);	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);	int ret = 0;	if (drv && drv->suspend)		ret = drv->suspend(ldev, state);	return ret;}static int locomo_bus_resume(struct device *dev){	struct locomo_dev *ldev = LOCOMO_DEV(dev);	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);	int ret = 0;	if (drv && drv->resume)		ret = drv->resume(ldev);	return ret;}static int locomo_bus_probe(struct device *dev){	struct locomo_dev *ldev = LOCOMO_DEV(dev);	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);	int ret = -ENODEV;	if (drv->probe)		ret = drv->probe(ldev);	return ret;}static int locomo_bus_remove(struct device *dev){	struct locomo_dev *ldev = LOCOMO_DEV(dev);	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);	int ret = 0;	if (drv->remove)		ret = drv->remove(ldev);	return ret;}struct bus_type locomo_bus_type = {	.name		= "locomo-bus",	.match		= locomo_match,	.probe		= locomo_bus_probe,	.remove		= locomo_bus_remove,	.suspend	= locomo_bus_suspend,	.resume		= locomo_bus_resume,};int locomo_driver_register(struct locomo_driver *driver){	driver->drv.bus = &locomo_bus_type;	return driver_register(&driver->drv);}void locomo_driver_unregister(struct locomo_driver *driver){	driver_unregister(&driver->drv);}static int __init locomo_init(void){	int ret = bus_register(&locomo_bus_type);	if (ret == 0)		platform_driver_register(&locomo_device_driver);	return ret;}static void __exit locomo_exit(void){	platform_driver_unregister(&locomo_device_driver);	bus_unregister(&locomo_bus_type);}module_init(locomo_init);module_exit(locomo_exit);MODULE_DESCRIPTION("Sharp LoCoMo core driver");MODULE_LICENSE("GPL");MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");EXPORT_SYMBOL(locomo_driver_register);EXPORT_SYMBOL(locomo_driver_unregister);EXPORT_SYMBOL(locomo_gpio_set_dir);EXPORT_SYMBOL(locomo_gpio_read_level);EXPORT_SYMBOL(locomo_gpio_read_output);EXPORT_SYMBOL(locomo_gpio_write);EXPORT_SYMBOL(locomo_m62332_senddata);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -