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

📄 dac3550a.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
字号:
/* * Driver for the i2c/i2s based DAC3550a sound chip used * on some Apple iBooks. Also known as "DACA". * *  This file is subject to the terms and conditions of the GNU General Public *  License.  See the file COPYING in the main directory of this archive *  for more details. */#include <linux/module.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/proc_fs.h>#include <linux/ioport.h>#include <linux/sysctl.h>#include <linux/types.h>#include <linux/i2c.h>#include <linux/init.h>#include <asm/uaccess.h>#include <asm/errno.h>#include <asm/io.h>#include "dmasound.h"/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer * control code, as well as info derived from the AppleDACAAudio driver * from Darwin CVS (main thing I derived being register numbers and  * values, as well as when to make the calls). */#define I2C_DRIVERID_DACA (0xFDCB)#define DACA_VERSION	"0.1"#define DACA_DATE "20010930"static int cur_left_vol;static int cur_right_vol;static struct i2c_client *daca_client;static int daca_attach_adapter(struct i2c_adapter *adapter);static int daca_detect_client(struct i2c_adapter *adapter, int address);static int daca_detach_client(struct i2c_client *client);/* Unique ID allocation */static int daca_id;struct i2c_driver daca_driver = {  	.owner			= THIS_MODULE,	.name			= "DAC3550A driver  V " DACA_VERSION,	.id			= I2C_DRIVERID_DACA,	.flags			= I2C_DF_NOTIFY,	.attach_adapter		= daca_attach_adapter,	.detach_client		= daca_detach_client,};#define VOL_MAX ((1<<20) - 1)void daca_get_volume(uint * left_vol, uint  *right_vol){	*left_vol = cur_left_vol >> 5;	*right_vol = cur_right_vol >> 5;}int daca_set_volume(uint left_vol, uint right_vol){	unsigned short voldata;  	if (!daca_client)		return -1;	/* Derived from experience, not from any specific values */	left_vol <<= 5;	right_vol <<= 5;	if (left_vol > VOL_MAX)		left_vol = VOL_MAX;	if (right_vol > VOL_MAX)		right_vol = VOL_MAX;	voldata = ((left_vol >> 14)  & 0x3f) << 8;	voldata |= (right_vol >> 14)  & 0x3f;  	if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {		printk("daca: failed to set volume \n");		return -1; 	}	cur_left_vol = left_vol;	cur_right_vol = right_vol;  	return 0;}int daca_leave_sleep(void){	if (!daca_client)		return -1;  	/* Do a short sleep, just to make sure I2C bus is awake and paying	 * attention to us	 */	msleep(20);	/* Write the sample rate reg the value it needs */	i2c_smbus_write_byte_data(daca_client, 1, 8);	daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);	/* Another short delay, just to make sure the other I2C bus writes	 * have taken...	 */	msleep(20);	/* Write the global config reg - invert right power amp,	 * DAC on, use 5-volt mode */	i2c_smbus_write_byte_data(daca_client, 3, 0x45);	return 0;}int daca_enter_sleep(void){	if (!daca_client)		return -1;	i2c_smbus_write_byte_data(daca_client, 1, 8);	daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);	/* Write the global config reg - invert right power amp,	 * DAC on, enter low-power mode, use 5-volt mode	 */	i2c_smbus_write_byte_data(daca_client, 3, 0x65);	return 0;}static int daca_attach_adapter(struct i2c_adapter *adapter){	if (!strncmp(adapter->name, "mac-io", 6))		daca_detect_client(adapter, 0x4d);	return 0;}static int daca_init_client(struct i2c_client * new_client){	/* 	 * Probe is not working with the current i2c-keywest	 * driver. We try to use addr 0x4d on each adapters	 * instead, by setting the format register.	 * 	 * FIXME: I'm sure that can be obtained from the	 * device-tree. --BenH.	 */  	/* Write the global config reg - invert right power amp,	 * DAC on, use 5-volt mode	 */	if (i2c_smbus_write_byte_data(new_client, 3, 0x45))		return -1;	i2c_smbus_write_byte_data(new_client, 1, 8);	daca_client = new_client;	daca_set_volume(15000, 15000);	return 0;}static int daca_detect_client(struct i2c_adapter *adapter, int address){	const char *client_name = "DAC 3550A Digital Equalizer";	struct i2c_client *new_client;	int rc = -ENODEV;	new_client = kmalloc(sizeof(*new_client), GFP_KERNEL);	if (!new_client)		return -ENOMEM;	memset(new_client, 0, sizeof(*new_client));	new_client->addr = address;	new_client->adapter = adapter;	new_client->driver = &daca_driver;	new_client->flags = 0;	strcpy(new_client->name, client_name);	new_client->id = daca_id++; /* racy... */	if (daca_init_client(new_client))		goto bail;	/* Tell the i2c layer a new client has arrived */	if (i2c_attach_client(new_client))		goto bail;	return 0; bail:	kfree(new_client);	return rc;}static int daca_detach_client(struct i2c_client *client){	if (client == daca_client)		daca_client = NULL;  	i2c_detach_client(client);	kfree(client);	return 0;}void daca_cleanup(void){	i2c_del_driver(&daca_driver);}int daca_init(void){	printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);	return i2c_add_driver(&daca_driver);}

⌨️ 快捷键说明

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