For the Conexant 5069 card I have found a way to mute the internal speakers.
.
Edit: I have now created a daemon to automattically mute and unmute the internal speakers when headphones are plugged in and removed.
Code:
/*
* File: main.cpp
* Author: xtr
*
* Created on April 26, 2010, 5:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/io.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <syslog.h>
#include <signal.h>
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
#define HDA_VERB(nid,verb,param) ((nid)<<24 | (verb)<<8 | (param))
#define HDA_IOCTL_VERB_WRITE _IOWR('H', 0x11, struct hda_verb_ioctl)
struct hda_verb_ioctl {
u32 verb; /* HDA_VERB() */
u32 res; /* response */
};
void daemonize()
{
pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
openlog("pinsensed", LOG_PID, LOG_DAEMON);
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log any failure here */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log any failure here */
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
bool done = false;
void trpsig(int)
{
done = true;
}
int main(int argc, char** argv) {
daemonize();
signal(SIGTERM, &trpsig);
int fd, state;
struct hda_verb_ioctl val;
syslog(LOG_INFO, "Daemon started.");
fd = open("/dev/snd/hwC0D0", O_RDWR);
if (fd < 0) {
syslog(LOG_ERR, "Failed to open snd device.");
exit(EXIT_FAILURE);
}
val.verb = HDA_VERB(0x19, 0x0f09, 0x0);
if (ioctl(fd, HDA_IOCTL_VERB_WRITE, &val) < 0)
syslog(LOG_ERR, "Failed to write hda verb.");
state = val.res >> 31;
syslog(LOG_INFO, "Starting input value: %0x", state);
while(!done)
{
sleep(1);
val.verb = HDA_VERB(0x19, 0x0f09, 0x0);
if (ioctl(fd, HDA_IOCTL_VERB_WRITE, &val) < 0)
syslog(LOG_ERR, "Failed to write hda verb.");
if(state != (val.res >> 31))
{
state = (val.res >> 31);
syslog(LOG_INFO, "New input value: %0x", state);
if(state == 0x1)
val.verb = HDA_VERB(0x1f, 0x701, 0x1);
else
val.verb = HDA_VERB(0x1f, 0x701, 0x0);
if (ioctl(fd, HDA_IOCTL_VERB_WRITE, &val) < 0)
syslog(LOG_ERR, "Failed to write hda verb.");
}
}
close(fd);
syslog(LOG_INFO, "Daemon stopped.");
exit(EXIT_SUCCESS);
}
Bookmarks