Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic * Add more AC97 modem registers (from AC'97 revis...
details: https://anonhg.NetBSD.org/src/rev/8421c34adea2
branches: trunk
changeset: 580010:8421c34adea2
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Mon Apr 04 18:52:30 2005 +0000
description:
* Add more AC97 modem registers (from AC'97 revision 2.2)
* Add sysctls to control the modem's off-hook status (work in progress)
diffstat:
sys/dev/ic/ac97.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++----
sys/dev/ic/ac97reg.h | 53 ++++++++++++++---
2 files changed, 182 insertions(+), 25 deletions(-)
diffs (truncated from 304 to 300 lines):
diff -r cf0740b6fe7f -r 8421c34adea2 sys/dev/ic/ac97.c
--- a/sys/dev/ic/ac97.c Mon Apr 04 18:43:55 2005 +0000
+++ b/sys/dev/ic/ac97.c Mon Apr 04 18:52:30 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ac97.c,v 1.67 2005/04/04 02:08:58 jmcneill Exp $ */
+/* $NetBSD: ac97.c,v 1.68 2005/04/04 18:52:30 jmcneill Exp $ */
/* $OpenBSD: ac97.c,v 1.8 2000/07/19 09:01:35 csapuntz Exp $ */
/*
@@ -63,13 +63,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ac97.c,v 1.67 2005/04/04 02:08:58 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ac97.c,v 1.68 2005/04/04 18:52:30 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/device.h>
+#include <sys/sysctl.h>
#include <sys/audioio.h>
#include <dev/audio_if.h>
@@ -102,6 +103,9 @@
static void ac97_alc650_init(struct ac97_softc *);
static void ac97_vt1616_init(struct ac97_softc *);
+static int ac97_modem_offhook_set(struct ac97_softc *, int, int);
+static int ac97_sysctl_verify(SYSCTLFN_ARGS);
+
#define Ac97Nphone "phone"
static const struct audio_mixer_enum
@@ -337,6 +341,13 @@
uint16_t ext_id; /* -> AC97_REG_EXT_AUDIO_ID */
uint16_t ext_mid; /* -> AC97_REG_EXT_MODEM_ID */
uint16_t shadow_reg[128];
+
+ /* sysctl */
+ struct sysctllog *log;
+ int offhook_line1_mib;
+ int offhook_line2_mib;
+ int offhook_line1;
+ int offhook_line2;
};
static struct ac97_codec_if_vtbl ac97civ = {
@@ -1109,8 +1120,12 @@
as->ext_mid = 0;
}
if (as->ext_mid != 0) {
+ struct sysctlnode *node;
+ struct sysctlnode *node_line1;
+ struct sysctlnode *node_line2;
uint16_t rate = 12000;
uint16_t val, reg;
+ int err;
/* Print capabilities */
bitmask_snprintf(as->ext_mid,
@@ -1122,40 +1137,93 @@
(as->ext_mid & 0xc000) == 0 ?
"primary" : "secondary");
- /* Setup modem */
- val = AC97_MEA_GPIO;
+ /* Setup modem and sysctls */
+ val = AC97_EXT_MODEM_CTRL_GPIO;
+ err = sysctl_createv(&as->log, 0, NULL, NULL, 0, CTLTYPE_NODE,
+ "hw", NULL, NULL, 0, NULL, 0, CTL_HW,
+ CTL_EOL);
+ if (err != 0)
+ goto sysctl_err;
+ err = sysctl_createv(&as->log, 0, NULL, &node, 0,
+ CTLTYPE_NODE, sc_dev->dv_xname, NULL,
+ NULL, 0, NULL, 0, CTL_HW, CTL_CREATE,
+ CTL_EOL);
+ if (err != 0)
+ goto sysctl_err;
if (as->ext_mid & AC97_EXT_MODEM_LINE1) {
ac97_write(as, AC97_REG_LINE1_RATE, rate);
- val |= AC97_MEA_ADC1 | AC97_MEA_DAC1;
+ val |= AC97_EXT_MODEM_CTRL_ADC1 |
+ AC97_EXT_MODEM_CTRL_DAC1;
}
if (as->ext_mid & AC97_EXT_MODEM_LINE2) {
ac97_write(as, AC97_REG_LINE2_RATE, rate);
- val |= AC97_MEA_ADC2 | AC97_MEA_DAC2;
+ val |= AC97_EXT_MODEM_CTRL_ADC2 |
+ AC97_EXT_MODEM_CTRL_DAC2;
}
if (as->ext_mid & AC97_EXT_MODEM_HANDSET) {
ac97_write(as, AC97_REG_HANDSET_RATE, rate);
- val |= AC97_MEA_HADC | AC97_MEA_HDAC;
+ val |= AC97_EXT_MODEM_CTRL_HADC |
+ AC97_EXT_MODEM_CTRL_HDAC;
}
- ac97_write(as, AC97_REG_EXT_MODEM_STATUS, 0xff00 & ~(val << 8));
+ /* power-up everything that we have */
+ ac97_write(as, AC97_REG_EXT_MODEM_CTRL, 0xff00 & ~(val << 8));
delay(100);
- ac97_write(as, AC97_REG_EXT_MODEM_STATUS, 0xff00 & ~(val << 8));
+ ac97_write(as, AC97_REG_EXT_MODEM_CTRL, 0xff00 & ~(val << 8));
+ i = 500000;
do {
- ac97_read(as, AC97_REG_EXT_MODEM_STATUS, ®);
+ ac97_read(as, AC97_REG_EXT_MODEM_CTRL, ®);
delay(1);
} while ((reg & val) != val && i--);
if (i == 0)
- printf("%s: error setting extended modem controls\n",
+ printf("%s: error setting extended modem status\n",
sc_dev->dv_xname);
- ac97_write(as, AC97_REG_GPIO_CFG,
- 0xffff & ~(AC97_GPIO_LINE1_OH));
- ac97_write(as, AC97_REG_GPIO_POLARITY,
- 0xffff & ~(AC97_GPIO_LINE1_OH));
+ /* setup sysctls */
+ if (as->ext_mid & AC97_EXT_MODEM_LINE1) {
+ ac97_read(as, AC97_REG_GPIO_CFG, ®);
+ reg &= ~AC97_GPIO_LINE1_OH;
+ ac97_write(as, AC97_REG_GPIO_CFG, reg);
+ ac97_read(as, AC97_REG_GPIO_POLARITY, ®);
+ reg &= ~AC97_GPIO_LINE1_OH;
+ ac97_write(as, AC97_REG_GPIO_POLARITY, reg);
+
+ err = sysctl_createv(&as->log, 0, NULL, &node_line1,
+ CTLFLAG_READWRITE, CTLTYPE_INT,
+ "line1",
+ SYSCTL_DESCR("off-hook line1"),
+ ac97_sysctl_verify, 0, as, 0,
+ CTL_HW, node->sysctl_num,
+ CTL_CREATE, CTL_EOL);
+ if (err != 0)
+ goto sysctl_err;
+ as->offhook_line1_mib = node_line1->sysctl_num;
+ }
+ if (as->ext_mid & AC97_EXT_MODEM_LINE2) {
+ ac97_read(as, AC97_REG_GPIO_CFG, ®);
+ reg &= ~AC97_GPIO_LINE2_OH;
+ ac97_write(as, AC97_REG_GPIO_CFG, reg);
+ ac97_read(as, AC97_REG_GPIO_POLARITY, ®);
+ reg &= ~AC97_GPIO_LINE2_OH;
+ ac97_write(as, AC97_REG_GPIO_POLARITY, reg);
+
+ err = sysctl_createv(&as->log, 0, NULL, &node_line2,
+ CTLFLAG_READWRITE, CTLTYPE_INT,
+ "line2",
+ SYSCTL_DESCR("off-hook line2"),
+ ac97_sysctl_verify, 0, as, 0,
+ CTL_HW, node->sysctl_num,
+ CTL_CREATE, CTL_EOL);
+ if (err != 0)
+ goto sysctl_err;
+ as->offhook_line2_mib = node_line2->sysctl_num;
+ }
+
ac97_write(as, AC97_REG_GPIO_STICKY, 0xffff);
ac97_write(as, AC97_REG_GPIO_WAKEUP, 0x0);
ac97_write(as, AC97_REG_MISC_AFE, 0x0);
}
+sysctl_err:
ac97_setup_source_info(as);
memset(&ctl, 0, sizeof(ctl));
@@ -1755,3 +1823,59 @@
ac97_add_port(as, &sources[1]);
ac97_add_port(as, &sources[2]);
}
+
+static int
+ac97_modem_offhook_set(struct ac97_softc *as, int line, int newval)
+{
+ uint16_t val = 0;
+
+ switch (newval) {
+ case 0:
+ val &= ~line;
+ break;
+ case 1:
+ val |= line;
+ break;
+ }
+ ac97_write(as, AC97_REG_GPIO_STATUS, val);
+
+ return 0;
+}
+
+static int
+ac97_sysctl_verify(SYSCTLFN_ARGS)
+{
+ int error, tmp;
+ struct sysctlnode node;
+ struct ac97_softc *as;
+
+ node = *rnode;
+ as = rnode->sysctl_data;
+ if (node.sysctl_num == as->offhook_line1_mib) {
+ tmp = as->offhook_line1;
+ node.sysctl_data = &tmp;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+
+ if (tmp < 0 || tmp > 1)
+ return EINVAL;
+
+ as->offhook_line1 = tmp;
+ ac97_modem_offhook_set(as, AC97_GPIO_LINE1_OH, tmp);
+ } else if (node.sysctl_num == as->offhook_line2_mib) {
+ tmp = as->offhook_line2;
+ node.sysctl_data = &tmp;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+
+ if (tmp < 0 || tmp > 1)
+ return EINVAL;
+
+ as->offhook_line2 = tmp;
+ ac97_modem_offhook_set(as, AC97_GPIO_LINE2_OH, tmp);
+ }
+
+ return 0;
+}
diff -r cf0740b6fe7f -r 8421c34adea2 sys/dev/ic/ac97reg.h
--- a/sys/dev/ic/ac97reg.h Mon Apr 04 18:43:55 2005 +0000
+++ b/sys/dev/ic/ac97reg.h Mon Apr 04 18:52:30 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ac97reg.h,v 1.10 2005/04/04 02:08:58 jmcneill Exp $ */
+/* $NetBSD: ac97reg.h,v 1.11 2005/04/04 18:52:30 jmcneill Exp $ */
/*
* Copyright (c) 1999 Constantine Sapuntzakis
@@ -142,15 +142,26 @@
#define AC97_EXT_MODEM_HANDSET 0x0004
#define AC97_EXT_MODEM_CID1 0x0008
#define AC97_EXT_MODEM_CID2 0x0010
-#define AC97_REG_EXT_MODEM_STATUS 0x3e /* extended modem status */
-#define AC97_MEA_GPIO 0x0001 /* gpio is ready */
-#define AC97_MEA_ADC1 0x0004
-#define AC97_MEA_DAC1 0x0008
-#define AC97_MEA_ADC2 0x0010
-#define AC97_MEA_DAC2 0x0020
-#define AC97_MEA_HADC 0x0040
-#define AC97_MEA_HDAC 0x0080
-
+#define AC97_EXT_MODEM_ID0 0x4000
+#define AC97_EXT_MODEM_ID1 0x8000
+#define AC97_EXT_MODEM_ID_MASK 0xc000
+#define AC97_REG_EXT_MODEM_CTRL 0x3e /* extended modem ctrl */
+#define AC97_EXT_MODEM_CTRL_GPIO 0x0001 /* gpio is ready */
+#define AC97_EXT_MODEM_CTRL_MREF 0x0002 /* vref up */
+#define AC97_EXT_MODEM_CTRL_ADC1 0x0004 /* line1 adc ready */
+#define AC97_EXT_MODEM_CTRL_DAC1 0x0008 /* line1 dac ready */
+#define AC97_EXT_MODEM_CTRL_ADC2 0x0010 /* line2 adc ready */
+#define AC97_EXT_MODEM_CTRL_DAC2 0x0020 /* line2 dac ready */
+#define AC97_EXT_MODEM_CTRL_HADC 0x0040 /* handset adc ready */
+#define AC97_EXT_MODEM_CTRL_HDAC 0x0080 /* handset dac ready */
+#define AC97_EXT_MODEM_CTRL_PRA 0x0100 /* gpio off */
+#define AC97_EXT_MODEM_CTRL_PRB 0x0200 /* vref off */
+#define AC97_EXT_MODEM_CTRL_PRC 0x0400 /* line1 adc off */
+#define AC97_EXT_MODEM_CTRL_PRD 0x0800 /* line1 dac off */
+#define AC97_EXT_MODEM_CTRL_PRE 0x1000 /* line2 adc off */
+#define AC97_EXT_MODEM_CTRL_PRF 0x2000 /* line2 dac off */
+#define AC97_EXT_MODEM_CTRL_PRG 0x4000 /* handset adc off */
+#define AC97_EXT_MODEM_CTRL_PRH 0x8000 /* handset dac off */
#define AC97_REG_LINE1_RATE 0x40
#define AC97_REG_LINE2_RATE 0x42
#define AC97_REG_HANDSET_RATE 0x44
@@ -165,7 +176,29 @@
#define AC97_GPIO_LINE1_OH 0x0001 /* off-hook */
#define AC97_GPIO_LINE1_RI 0x0002 /* ring detect */
#define AC97_GPIO_LINE1_CID 0x0004 /* caller-id */
+#define AC97_GPIO_LINE2_OH 0x0400 /* off-hook */
+#define AC97_GPIO_LINE2_RI 0x0800 /* ring detect */
+#define AC97_GPIO_LINE2_CID 0x1000 /* caller-id */
#define AC97_REG_MISC_AFE 0x56 /* misc modem afe status & control */
+#define AC97_MISC_AFE_L1B_MASK 0x0007 /* line1 loopback */
+#define AC97_MISC_AFE_L2B_MASK 0x0070 /* line2 loopback */
+#define AC97_MISC_AFE_HSB_MASK 0x0700 /* handset loopback */
+#define AC97_MISC_AFE_MLNK 0x1000 /* ac-link status */
+#define AC97_MISC_AFE_CID1 0x2000 /* line1 cid decode */
+#define AC97_MISC_AFE_CID2 0x4000 /* line2 cid decide */
+#define AC97_MISC_AFE_CIDR 0x8000 /* raw cid data */
+
+/* Modem loopback modes */
+#define AC97_LOOPBACK_DISABLE 0
+#define AC97_LOOPBACK_ADC 1
+#define AC97_LOOPBACK_LOCAL_ANALOG 2
+#define AC97_LOOPBACK_DAC 3
+#define AC97_LOOPBACK_REMOTE_ANALOG 4
+#define AC97_LOOPBACK_VENDOR1 5
+#define AC97_LOOPBACK_VENDOR2 6
+#define AC97_LOOPBACK_VENDOR3 7
+
Home |
Main Index |
Thread Index |
Old Index