程序说明:此驱动不同于以往的 linux ds18b20 驱动,不采用软延时,采用的是am3517 的单总线控制器,参考了TI有关HDQ/w1驱动,经测试,能正确输出温度。
/*
* sdq_ds18b20.c
*
* Copyright (c) 2012 Embeded2
*
* Some code and ideas taken from drivers/w1/master/omap_hdq.c driver
* by TI.
*
* This program is free software; you can redistribute it and/or modify
* it under the therms 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 <asm/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/genhd.h>
#include <asm/irq.h>
#include <mach/hardware.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Embeded2");
MODULE_DESCRIPTION("Driver for 1-wire Dallas ds18b20");
#define OMAP_HDQ_BASE 0x480B2000
#define OMAP_HDQ_REVISION 0x00
#define OMAP_HDQ_TX_DATA 0x04
#define OMAP_HDQ_RX_DATA 0x08
#define OMAP_HDQ_CTRL_STATUS 0x0c
#define OMAP_HDQ_INT_STATUS 0x10
#define OMAP_HDQ_SYSCONFIG 0x14
#define OMAP_HDQ_SYSSTATUS 0x18
#define OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK (1<<6)
#define OMAP_HDQ_CTRL_STATUS_CLOCKENABLE (1<<5)
#define OMAP_HDQ_CTRL_STATUS_GO (1<<4)
#define OMAP_HDQ_CTRL_STATUS_INITIALIZATION (1<<2)
#define OMAP_HDQ_CTRL_STATUS_DIR (1<<1)
#define OMAP_HDQ_CTRL_STATUS_MODE (1<<0)
#define OMAP_HDQ_INT_STATUS_TXCOMPLETE (1<<2)
#define OMAP_HDQ_INT_STATUS_RXCOMPLETE (1<<1)
#define OMAP_HDQ_INT_STATUS_TIMEOUT (1<<0)
#define OMAP_HDQ_SYSCONFIG_SOFTRESET (1<<1)
#define OMAP_HDQ_SYSCONFIG_AUTOIDLE (1<<0)
#define OMAP_HDQ_SYSSTATUS_RESETDONE (1<<0)
#define OMAP_HDQ_FLAG_CLEAR 0
#define OMAP_HDQ_FLAG_SET 1
#define OMAP_HDQ_TIMEOUT (HZ/5)
#define OMAP_HDQ_MAX_USER 4
#define DEVICE_NAME "ds18b20"
#define W1_SEARCH 0xF0
#define W1_ALARM_SEARCH 0xEC
#define W1_CONVERT_TEMP 0x44
#define W1_SKIP_ROM 0xCC
#define W1_READ_SCRATCHPAD 0xBE
#define W1_READ_ROM 0x33
#define W1_READ_PSUPPLY 0xB4
#define W1_MATCH_ROM 0x55
static DECLARE_WAIT_QUEUE_HEAD(hdq_wait_queue);
struct DS18B20_DEV {
void __iomem *hdq_base;
/* lock status update */
struct mutex hdq_mutex;
int hdq_usecount;
struct clk *hdq_ick;
struct clk *hdq_fck;
u8 hdq_irqstatus;
/* device lock */
spinlock_t hdq_spinlock;
};
static struct DS18B20_DEV ds18b20_dev;
static int __init omap_hdq_probe(struct platform_device *pdev);
static int omap_hdq_remove(struct platform_device *pdev);
static inline u8 hdq_reg_in(struct DS18B20_DEV *hdq_data, u32 offset)
{
return __raw_readb(hdq_data->hdq_base + offset);
}
static inline void hdq_reg_out(struct DS18B20_DEV *hdq_data, u32 offset, u8 val)
{
__raw_writeb(val, hdq_data->hdq_base + offset);
}
static inline u8 hdq_reg_merge(struct DS18B20_DEV *hdq_data, u32 offset,
u8 val, u8 mask)
{
u8 new_val = (__raw_readb(hdq_data->hdq_base + offset) & ~mask
/*
* sdq_ds18b20.c
*
* Copyright (c) 2012 Embeded2
*
* Some code and ideas taken from drivers/w1/master/omap_hdq.c driver
* by TI.
*
* This program is free software; you can redistribute it and/or modify
* it under the therms 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 <asm/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/genhd.h>
#include <asm/irq.h>
#include <mach/hardware.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Embeded2");
MODULE_DESCRIPTION("Driver for 1-wire Dallas ds18b20");
#define OMAP_HDQ_BASE 0x480B2000
#define OMAP_HDQ_REVISION 0x00
#define OMAP_HDQ_TX_DATA 0x04
#define OMAP_HDQ_RX_DATA 0x08
#define OMAP_HDQ_CTRL_STATUS 0x0c
#define OMAP_HDQ_INT_STATUS 0x10
#define OMAP_HDQ_SYSCONFIG 0x14
#define OMAP_HDQ_SYSSTATUS 0x18
#define OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK (1<<6)
#define OMAP_HDQ_CTRL_STATUS_CLOCKENABLE (1<<5)
#define OMAP_HDQ_CTRL_STATUS_GO (1<<4)
#define OMAP_HDQ_CTRL_STATUS_INITIALIZATION (1<<2)
#define OMAP_HDQ_CTRL_STATUS_DIR (1<<1)
#define OMAP_HDQ_CTRL_STATUS_MODE (1<<0)
#define OMAP_HDQ_INT_STATUS_TXCOMPLETE (1<<2)
#define OMAP_HDQ_INT_STATUS_RXCOMPLETE (1<<1)
#define OMAP_HDQ_INT_STATUS_TIMEOUT (1<<0)
#define OMAP_HDQ_SYSCONFIG_SOFTRESET (1<<1)
#define OMAP_HDQ_SYSCONFIG_AUTOIDLE (1<<0)
#define OMAP_HDQ_SYSSTATUS_RESETDONE (1<<0)
#define OMAP_HDQ_FLAG_CLEAR 0
#define OMAP_HDQ_FLAG_SET 1
#define OMAP_HDQ_TIMEOUT (HZ/5)
#define OMAP_HDQ_MAX_USER 4
#define DEVICE_NAME "ds18b20"
#define W1_SEARCH 0xF0
#define W1_ALARM_SEARCH 0xEC
#define W1_CONVERT_TEMP 0x44
#define W1_SKIP_ROM 0xCC
#define W1_READ_SCRATCHPAD 0xBE
#define W1_READ_ROM 0x33
#define W1_READ_PSUPPLY 0xB4
#define W1_MATCH_ROM 0x55
static DECLARE_WAIT_QUEUE_HEAD(hdq_wait_queue);
struct DS18B20_DEV {
void __iomem *hdq_base;
/* lock status update */
struct mutex hdq_mutex;
int hdq_usecount;
struct clk *hdq_ick;
struct clk *hdq_fck;
u8 hdq_irqstatus;
/* device lock */
spinlock_t hdq_spinlock;
};
static struct DS18B20_DEV ds18b20_dev;
static int __init omap_hdq_probe(struct platform_device *pdev);
static int omap_hdq_remove(struct platform_device *pdev);
static inline u8 hdq_reg_in(struct DS18B20_DEV *hdq_data, u32 offset)
{
return __raw_readb(hdq_data->hdq_base + offset);
}
static inline void hdq_reg_out(struct DS18B20_DEV *hdq_data, u32 offset, u8 val)
{
__raw_writeb(val, hdq_data->hdq_base + offset);
}
static inline u8 hdq_reg_merge(struct DS18B20_DEV *hdq_data, u32 offset,
u8 val, u8 mask)
{
u8 new_val = (__raw_readb(hdq_data->hdq_base + offset) & ~mask