OK335xS pwm device register hacking

时间:2023-12-27 10:45:07
/*************************************************************************
* OK335xS pwm device register hacking
* 声明:
* 本文是对OK335xS pwm设备注册进行代码跟踪,其中有些部分是由于本人自己
* 添加的,但都是经过测试。
*
* 2015-8-25 晴 深圳 南山平山村 曾剑锋
************************************************************************/
MACHINE_START(AM335XEVM, "am335xevm")
/* Maintainer: Texas Instruments */
.atag_offset = 0x100,
.map_io = am335x_evm_map_io,
.init_early = am33xx_init_early,
.init_irq = ti81xx_init_irq,
.handle_irq = omap3_intc_handle_irq,
.timer = &omap3_am33xx_timer,
.init_machine = am335x_evm_init, ---------+
MACHINE_END |
|
MACHINE_START(AM335XIAEVM, "am335xiaevm") |
/* Maintainer: Texas Instruments */ |
.atag_offset = 0x100, |
.map_io = am335x_evm_map_io, |
.init_irq = ti81xx_init_irq, |
.init_early = am33xx_init_early, |
.timer = &omap3_am33xx_timer, |
.init_machine = am335x_evm_init, |
MACHINE_END |
|
|
static void __init am335x_evm_init(void) <--------+
{
......
setup_ok335xs(); ---------+
...... |
} |
|
static void setup_ok335xs(void) <--------+
{
pr_info("The board is a ok335xs.\n"); /* Starter Kit has Micro-SD slot which doesn't have Write Protect pin */
am335x_mmc[].gpio_wp = -EINVAL; _configure_device(EVM_SK, ok335xs_dev_cfg, PROFILE_NONE); --------+
|
am33xx_cpsw_init(AM33XX_CPSW_MODE_RGMII, NULL, NULL); |
/* Atheros Tx Clk delay Phy fixup */ |
phy_register_fixup_for_uid(AM335X_EVM_PHY_ID, AM335X_EVM_PHY_MASK, |
am33xx_evm_tx_clk_dly_phy_fixup); |
} |
|
static struct evm_dev_cfg ok335xs_dev_cfg[] = { <-------+
{mmc0_init, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed
#if defined(CONFIG_ANDROID)
{mfd_tscadc_init, DEV_ON_BASEBOARD, PROFILE_ALL},
#endif
{rgmii1_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{rgmii2_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{lcdc_init, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed
{i2c1_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{buzzer_init, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed --------+
{enable_ecap2, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed |
{usb0_init, DEV_ON_BASEBOARD, PROFILE_ALL}, |
{usb1_init, DEV_ON_BASEBOARD, PROFILE_ALL}, |
{evm_nand_init,DEV_ON_BASEBOARD, PROFILE_ALL},//fixed |
{mcasp1_init, DEV_ON_BASEBOARD, PROFILE_NONE},//fixed |
{gpio_keys_init_forlinx_s, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed |
{gpio_led_init_s, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed |
{uart2_init_s, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed |
{spi1_init_s, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed |
{d_can_init, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed |
{sgx_init, DEV_ON_BASEBOARD, PROFILE_ALL}, |
{NULL, , }, |
}; |
|
static void buzzer_init(int evm_id, int profile) <--------+
{
//setup_pin_mux(ecap0_pin_mux);
setup_pin_mux(ecap1_pin_mux); -----+ -------------------+
am33xx_register_ecap(, &pwm_pdata[]); ----*---------------------*+-+
} | || |
| || |
/* Module pin mux for eCAP1 */ | || |
static struct pinmux_config ecap1_pin_mux[] = { <----+ || |
{"spi0_cs1.ecap1_in_pwm1_out", -----+ || |
OMAP_MUX_MODE2 | AM33XX_PIN_OUTPUT}, | ---------------------+ || |
{NULL, }, | | || |
}; | | || |
| | || |
/* AM33XX pin mux super set */ | | || |
static struct omap_mux am33xx_muxmodes[] = { | --------------*+|| |
...... | |||| |
_AM33XX_MUXENTRY(SPI0_CS1, , V |||| |
//"spi0_cs1", "uart3_rxd", NULL, "mmc0_pow", |||| |
"spi0_cs1", "uart3_rxd", "ecap1_in_pwm1_out", "mmc0_pow", |||| |
NULL, "mmc0_sdcd", NULL, "gpio0_6"), |||| |
...... |||| |
} |||| |
|||| |
|||| |
/* 34xx mux mode options for each pin. See TRM for options */ |||| |
#define OMAP_MUX_MODE0 0 |||| |
#define OMAP_MUX_MODE1 1 |||| |
#define OMAP_MUX_MODE2 2 <-------------------------------------+||| |
#define OMAP_MUX_MODE3 3 ||| |
#define OMAP_MUX_MODE4 4 ||| |
#define OMAP_MUX_MODE5 5 ||| |
#define OMAP_MUX_MODE6 6 ||| |
#define OMAP_MUX_MODE7 7 ||| |
||| |
/* module pin mux structure */ ||| |
struct pinmux_config { <-------------------+|| |
const char *string_name; /* signal name format */ || |
int val; /* Options for the mux register value */ || |
}; || |
|| |
static void setup_pin_mux(struct pinmux_config *pin_mux) <---------------+| |
{ | |
int i; | |
| |
for (i = ; pin_mux->string_name != NULL; pin_mux++) | |
omap_mux_init_signal(pin_mux->string_name, pin_mux->val); --------+ | |
| | |
} | | |
| | |
int __init omap_mux_init_signal(const char *muxname, int val) <-------+ | |
{ | |
struct omap_mux_partition *partition = NULL; | |
struct omap_mux *mux = NULL; | |
u16 old_mode; | |
int mux_mode; | |
| |
mux_mode = omap_mux_get_by_name(muxname, &partition, &mux); --------+ | |
if (mux_mode < ) | | |
return mux_mode; | | |
| | |
old_mode = omap_mux_read(partition, mux->reg_offset); | | |
mux_mode |= val; | | |
pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n", | | |
__func__, muxname, old_mode, mux_mode); | | |
omap_mux_write(partition, mux_mode, mux->reg_offset); | | |
| | |
return ; | | |
} | | |
| | |
int omap_mux_get_by_name(const char *muxname, <-------+ | |
struct omap_mux_partition **found_partition, | |
struct omap_mux **found_mux) | |
{ | |
struct omap_mux_partition *partition; | |
| |
list_for_each_entry(partition, &mux_partitions, node) { | |
struct omap_mux *mux = NULL; | |
int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux); ---+ | |
if (mux_mode < ) | | |
continue; | | |
| | |
*found_partition = partition; | | |
*found_mux = mux; | | |
| | |
return mux_mode; +--------------------------------------------+ | |
} | | |
| | |
return -ENODEV; | | |
} | | |
V | |
static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, | |
const char *muxname, | |
struct omap_mux **found_mux) | |
{ | |
struct omap_mux *mux = NULL; | |
struct omap_mux_entry *e; | |
const char *mode_name; | |
int found = , found_mode = , mode0_len = ; | |
struct list_head *muxmodes = &partition->muxmodes; | |
| |
mode_name = strchr(muxname, '.'); | |
if (mode_name) { | |
mode0_len = strlen(muxname) - strlen(mode_name); | |
mode_name++; | |
} else { | |
mode_name = muxname; | |
} | |
| |
list_for_each_entry(e, muxmodes, node) { | |
char *m0_entry; | |
int i; | |
| |
mux = &e->mux; | |
m0_entry = mux->muxnames[]; | |
| |
/* First check for full name in mode0.muxmode format */ | |
if (mode0_len && strncmp(muxname, m0_entry, mode0_len)) | |
continue; | |
| |
/* Then check for muxmode only */ | |
for (i = ; i < OMAP_MUX_NR_MODES; i++) { | |
char *mode_cur = mux->muxnames[i]; | |
| |
if (!mode_cur) | |
continue; | |
| |
if (!strcmp(mode_name, mode_cur)) { | |
*found_mux = mux; | |
found++; | |
found_mode = i; | |
} | |
} | |
} | |
| |
if (found == ) { | |
return found_mode; | |
} | |
| |
if (found > ) { | |
pr_err("%s: Multiple signal paths (%i) for %s\n", __func__, | |
found, muxname); | |
return -EINVAL; | |
} | |
| |
pr_err("%s: Could not find signal %s\n", __func__, muxname); | |
| |
return -ENODEV; | |
} | |
| |
static struct pwmss_platform_data pwm_pdata[] = { <----------------+ |
{ |
.version = PWM_VERSION_1, |
}, |
{ |
.version = PWM_VERSION_1, |
}, |
{ |
.version = PWM_VERSION_1, |
}, |
}; |
|
#ifdef CONFIG_SOC_OMAPAM33XX |
#define PWM_STR_LEN 10 |
int __init am33xx_register_ecap(int id, struct pwmss_platform_data *pdata) <---+
{
struct platform_device *pdev;
struct omap_hwmod *oh;
char *oh_name = "ecap";
char dev_name[PWM_STR_LEN]; sprintf(dev_name, "ecap.%d", id); // for driver to match device name oh = omap_hwmod_lookup(dev_name);
if (!oh) {
pr_err("Could not look up %s hwmod\n", dev_name);
return -ENODEV;
} pdev = omap_device_build(oh_name, id, oh, pdata,
sizeof(*pdata), NULL, , ); if (IS_ERR(pdev)) {
WARN(, "Can't build omap_device for %s:%s.\n",
dev_name, oh->name);
return PTR_ERR(pdev);
}
return ;
}