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

📄 dscore.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	dscore.c * * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> * * * 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 program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <linux/module.h>#include <linux/kernel.h>#include <linux/mod_devicetable.h>#include <linux/usb.h>#include "dscore.h"static struct usb_device_id ds_id_table [] = {	{ USB_DEVICE(0x04fa, 0x2490) },	{ },};MODULE_DEVICE_TABLE(usb, ds_id_table);static int ds_probe(struct usb_interface *, const struct usb_device_id *);static void ds_disconnect(struct usb_interface *);int ds_touch_bit(struct ds_device *, u8, u8 *);int ds_read_byte(struct ds_device *, u8 *);int ds_read_bit(struct ds_device *, u8 *);int ds_write_byte(struct ds_device *, u8);int ds_write_bit(struct ds_device *, u8);static int ds_start_pulse(struct ds_device *, int);int ds_reset(struct ds_device *, struct ds_status *);struct ds_device * ds_get_device(void);void ds_put_device(struct ds_device *);static inline void ds_dump_status(unsigned char *, unsigned char *, int);static int ds_send_control(struct ds_device *, u16, u16);static int ds_send_control_mode(struct ds_device *, u16, u16);static int ds_send_control_cmd(struct ds_device *, u16, u16);static struct usb_driver ds_driver = {	.name =		"DS9490R",	.probe =	ds_probe,	.disconnect =	ds_disconnect,	.id_table =	ds_id_table,};static struct ds_device *ds_dev;struct ds_device * ds_get_device(void){	if (ds_dev)		atomic_inc(&ds_dev->refcnt);	return ds_dev;}void ds_put_device(struct ds_device *dev){	atomic_dec(&dev->refcnt);}static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index){	int err;	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),			CONTROL_CMD, 0x40, value, index, NULL, 0, 1000);	if (err < 0) {		printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n",				value, index, err);		return err;	}	return err;}static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index){	int err;	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),			MODE_CMD, 0x40, value, index, NULL, 0, 1000);	if (err < 0) {		printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n",				value, index, err);		return err;	}	return err;}static int ds_send_control(struct ds_device *dev, u16 value, u16 index){	int err;	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),			COMM_CMD, 0x40, value, index, NULL, 0, 1000);	if (err < 0) {		printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n",				value, index, err);		return err;	}	return err;}static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off){	printk("%45s: %8x\n", str, buf[off]);}static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,				 unsigned char *buf, int size){	int count, err;	memset(st, 0, sizeof(st));	count = 0;	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100);	if (err < 0) {		printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err);		return err;	}	if (count >= sizeof(*st))		memcpy(st, buf, sizeof(*st));	return count;}static int ds_recv_status(struct ds_device *dev, struct ds_status *st){	unsigned char buf[64];	int count, err = 0, i;	memcpy(st, buf, sizeof(*st));	count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));	if (count < 0)		return err;	printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);	for (i=0; i<count; ++i)		printk("%02x ", buf[i]);	printk("\n");	if (count >= 16) {		ds_dump_status(buf, "enable flag", 0);		ds_dump_status(buf, "1-wire speed", 1);		ds_dump_status(buf, "strong pullup duration", 2);		ds_dump_status(buf, "programming pulse duration", 3);		ds_dump_status(buf, "pulldown slew rate control", 4);		ds_dump_status(buf, "write-1 low time", 5);		ds_dump_status(buf, "data sample offset/write-0 recovery time", 6);		ds_dump_status(buf, "reserved (test register)", 7);		ds_dump_status(buf, "device status flags", 8);		ds_dump_status(buf, "communication command byte 1", 9);		ds_dump_status(buf, "communication command byte 2", 10);		ds_dump_status(buf, "communication command buffer status", 11);		ds_dump_status(buf, "1-wire data output buffer status", 12);		ds_dump_status(buf, "1-wire data input buffer status", 13);		ds_dump_status(buf, "reserved", 14);		ds_dump_status(buf, "reserved", 15);	}	memcpy(st, buf, sizeof(*st));	if (st->status & ST_EPOF) {		printk(KERN_INFO "Resetting device after ST_EPOF.\n");		err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);		if (err)			return err;		count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));		if (count < 0)			return err;	}#if 0	if (st->status & ST_IDLE) {		printk(KERN_INFO "Resetting pulse after ST_IDLE.\n");		err = ds_start_pulse(dev, PULLUP_PULSE_DURATION);		if (err)			return err;	}#endif	return err;}static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size){	int count, err;	struct ds_status st;	count = 0;	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),				buf, size, &count, 1000);	if (err < 0) {		printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);		usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));		ds_recv_status(dev, &st);		return err;	}#if 0	{		int i;		printk("%s: count=%d: ", __func__, count);		for (i=0; i<count; ++i)			printk("%02x ", buf[i]);		printk("\n");	}#endif	return count;}static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len){	int count, err;	count = 0;	err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);	if (err < 0) {		printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err);		return err;	}	return err;}#if 0int ds_stop_pulse(struct ds_device *dev, int limit){	struct ds_status st;	int count = 0, err = 0;	u8 buf[0x20];	do {		err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);		if (err)			break;		err = ds_send_control(dev, CTL_RESUME_EXE, 0);		if (err)			break;		err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));		if (err)			break;		if ((st.status & ST_SPUA) == 0) {			err = ds_send_control_mode(dev, MOD_PULSE_EN, 0);			if (err)				break;		}	} while(++count < limit);	return err;}int ds_detect(struct ds_device *dev, struct ds_status *st){	int err;	err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);	if (err)		return err;	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0);	if (err)		return err;	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40);	if (err)		return err;	err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG);	if (err)		return err;	err = ds_recv_status(dev, st);	return err;}#endif  /*  0  */static int ds_wait_status(struct ds_device *dev, struct ds_status *st){	u8 buf[0x20];	int err, count = 0;	do {		err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));#if 0		if (err >= 0) {			int i;			printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);			for (i=0; i<err; ++i)				printk("%02x ", buf[i]);			printk("\n");		}#endif	} while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100);	if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) {		ds_recv_status(dev, st);		return -1;	} else		return 0;}int ds_reset(struct ds_device *dev, struct ds_status *st){	int err;	//err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE);	err = ds_send_control(dev, 0x43, SPEED_NORMAL);	if (err)		return err;	ds_wait_status(dev, st);#if 0	if (st->command_buffer_status) {		printk(KERN_INFO "Short circuit.\n");		return -EIO;	}#endif	return 0;}#if 0int ds_set_speed(struct ds_device *dev, int speed){	int err;	if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE)		return -EINVAL;	if (speed != SPEED_OVERDRIVE)		speed = SPEED_FLEXIBLE;	speed &= 0xff;	err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed);	if (err)		return err;	return err;}#endif  /*  0  */static int ds_start_pulse(struct ds_device *dev, int delay){	int err;	u8 del = 1 + (u8)(delay >> 4);	struct ds_status st;#if 0	err = ds_stop_pulse(dev, 10);	if (err)		return err;	err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);	if (err)		return err;#endif	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del);	if (err)		return err;	err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0);	if (err)		return err;	mdelay(delay);	ds_wait_status(dev, &st);	return err;}int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)

⌨️ 快捷键说明

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