- 论坛徽章:
- 0
|
Normal
0
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
MicrosoftInternetExplorer4
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-font-kerning:1.0pt;}
ANDROID
GSM Modem 内核和应用层交互
参考 Neo1973代码。Kernel与API 交互机制
Kenel部分,主要代码:
Neo1973_pm_gsm.c (arch\arm\plat-s3c24xx)
生成属性文件路径:
#define GSM_POWER
"/sys/class/i2c-adapter/i2c-0/0-0073/neo1973-pm-gsm.0/power_on"
分析:
module_init(gta01_gsm_init);
--》platform_driver_register(>a01_gsm_driver);
---》
static
struct platform_driver gta01_gsm_driver = {
.probe = gta01_gsm_probe,
.remove = gta01_gsm_remove,
.suspend = gta01_gsm_suspend,
.suspend_late = gta01_gsm_suspend_late,
.resume = gta01_gsm_resume,
.driver = {
.name = "neo1973-pm-gsm",},
module_exit(gta01_gsm_exit);
--》platform_driver_unregister(>a01_gsm_driver);
//初始GSM MODEM
static int __init gta01_gsm_probe(struct
platform_device *pdev)
{
/* GSM is to be initially off (at boot, or if
this module inserted) */
gsm_on_off(&pdev->dev,
0);//关闭GSM
//关键,创建设备属性,以便和AP交互。
return
sysfs_create_group(&pdev->dev.kobj, >a01_gsm_attr_group);
}
GSM MODEM驱动纤细的属性定义:
static DEVICE_ATTR(power_on, 0644,
gsm_read, gsm_write);
static DEVICE_ATTR(reset, 0644, gsm_read,
gsm_write);
static DEVICE_ATTR(download, 0644,
gsm_read, gsm_write);
static DEVICE_ATTR(flowcontrolled, 0644, gsm_read,
gsm_write);
static struct attribute
*gta01_gsm_sysfs_entries[] = {
&dev_attr_power_on.attr,
&dev_attr_reset.attr,
&dev_attr_download.attr,
&dev_attr_flowcontrolled.attr,
NULL
};
static struct attribute_group
gta01_gsm_attr_group = {
.name = NULL,
.attrs = gta01_gsm_sysfs_entries,
};
改变属性动作:
/*
读取状态
*/
static ssize_t gsm_read(struct device *dev,
struct device_attribute *attr,
char
*buf)
{
if
(!strcmp(attr->attr.name, "power_on")) {
if
(gta01_gsm.gpio_ngsm_en) {
if
(!s3c2410_gpio_getpin(gta01_gsm.gpio_ngsm_en))
goto
out_1;
}
else if (machine_is_neo1973_gta02())
if
(pcf50633_gpio_get(gta02_pcf, PCF50633_GPIO2))
goto
out_1;
}
else if (!strcmp(attr->attr.name, "download")) {
if
(machine_is_neo1973_gta01()) {
if
(s3c2410_gpio_getpin(GTA01_GPIO_MODEM_DNLOAD))
goto
out_1;
}
else if (machine_is_neo1973_gta02()) {
if
(!s3c2410_gpio_getpin(GTA02_GPIO_nDL_GSM))
goto
out_1;
}
}
else if (!strcmp(attr->attr.name, "flowcontrolled")) {
if
(s3c2410_gpio_getcfg(S3C2410_GPH1) == S3C2410_GPIO_OUTPUT)
goto
out_1;
}
return
strlcpy(buf, "0\n", 3);
out_1:
return
strlcpy(buf, "1\n", 3);
}
/*
写入
*/
static ssize_t gsm_write(struct device
*dev, struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned
long on = simple_strtoul(buf, NULL, 10);
if
(!strcmp(attr->attr.name, "power_on")) {
gsm_on_off(dev,
on);
return
count;
}
if
(!strcmp(attr->attr.name, "download")) {
if
(machine_is_neo1973_gta01())
s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD,
on);
if
(machine_is_neo1973_gta02()) {
/*
* the keyboard / buttons driver requests and
enables
* the JACK_INSERT IRQ. We have to take care about
* not enabling and disabling the IRQ when it
was
* already in that state or we get
"unblanaced IRQ"
* kernel warnings and stack dumps. So we use the
* copy of the ndl_gsm state to figure out if
we should
* enable or disable the jack interrupt
*/
if
(on) {
if
(gta01_gsm.gpio_ndl_gsm)
disable_irq(gpio_to_irq(
GTA02_GPIO_JACK_INSERT));
}
else {
if
(!gta01_gsm.gpio_ndl_gsm)
enable_irq(gpio_to_irq(
GTA02_GPIO_JACK_INSERT));
}
gta01_gsm.gpio_ndl_gsm
= !on;
s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM,
!on);
}
return
count;
}
if
(!strcmp(attr->attr.name, "flowcontrolled")) {
if
(on) {
gta_gsm_interrupts
= 0;
s3c2410_gpio_setpin(S3C2410_GPH1,
1);
s3c2410_gpio_cfgpin(S3C2410_GPH1,
S3C2410_GPH1_OUTP);
}
else
s3c2410_gpio_cfgpin(S3C2410_GPH1,
S3C2410_GPH1_nRTS0);
}
return
count;
}
ANDROID AP层
在Virtual-channel.c (hardware\ril\vchanneld)文件中
在int open_phy_device(struct phy_device *phy, char *serial)
{
char
gsm_power[PROPERTY_VALUE_MAX];
char
gsm_reset[PROPERTY_VALUE_MAX];
//获取属性
property_get(POWER_GSM_PROPERTY,
gsm_reset, GSM_RESET);
property_get(POWER_GSM_PROPERTY,
gsm_power, GSM_POWER);
/*
switch off sequence */
gsm_set(gsm_power,
0); //引发内核驱动代码GSM_WRITE,关闭GSM的电源
sleep(1);
gsm_set(gsm_reset,
0);
sleep(1);
/*
switch on sequence */
gsm_set(gsm_power,
1);
sleep(1);
gsm_set(gsm_reset,
1);
sleep(1);
gsm_set(gsm_reset,
0);
sleep(4); //完成GSM MODEM 关机,开机操作
}
//
static void gsm_set(char *path, int on)
{
int
fd, ret;
char
cmd;
do
{
fd
= open(path, O_RDWR);
}
while (fd
if
(fd
LOGE("could
not open GSM");
return;
}
if
(on)
cmd
= '1';
else
cmd
= '0';
do
{
ret
= write(fd, &cmd, 1);
}
while (ret
close(fd);
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/64117/showart_2125959.html |
|