Skip to content

Commit

Permalink
configure modes for irq pin (pullup/down on/off) at runtime depending…
Browse files Browse the repository at this point in the history
… on module type (rfm12/rfm69).
  • Loading branch information
gkaindl committed May 14, 2015
1 parent cc99423 commit 187c5c4
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 24 deletions.
53 changes: 50 additions & 3 deletions platform/plat_beaglebone.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ struct am33xx_pinmux_settings {
static struct am33xx_pinmux_settings pinmux_settings[] = {
{
// beaglebone pin p9/27 (mcasp0_fsr)
// set as GPIO3_19 (mode 7), PULLUP ENABLED, INPUT ENABLED
// set as GPIO3_19 (mode 7), input, pull-state defined per-board type
.pin_addr = AM33XX_CONTROL_BASE + 0x9a4,
.settings = 0x7 | (1 << 3) | (1 << 5) // TODO!!! PULLUP ENABLED, FUCK!!!
.settings = 0x7 | (0 << 3) | (1 << 5) // TODO!!! PULLUP ENABLED, FUCK!!!
},
{
// beaglebone pin p9/42 (ecap0_in_pwm0_out)
Expand Down Expand Up @@ -122,13 +122,18 @@ static struct am33xx_pinmux_settings pinmux_settings[] = {
static int
spi_rfm12_init_pinmux_settings(void);
static int
spi_rfm12_init_irq_pin_settings(rfm12_module_type_t module_type);
static int
spi_rfm12_cleanup_pinmux_settings(void);
static int
spi_rfm12_cleanup_irq_pin_settings(rfm12_module_type_t module_type);

static int
spi_rfm12_init_pinmux_settings(void)
{
void* addr = NULL;
struct am33xx_pinmux_settings* pin_conf = &pinmux_settings[0];
// first pinmux_setting is the IRQ pin, which is treated specially
struct am33xx_pinmux_settings* pin_conf = &pinmux_settings[1];

while (0 != pin_conf->pin_addr) {
addr = ioremap(pin_conf->pin_addr, 4);
Expand All @@ -153,10 +158,52 @@ spi_rfm12_init_pinmux_settings(void)
return 0;
}

static int
spi_rfm12_init_irq_pin_settings(rfm12_module_type_t module_type)
{
void* addr = NULL;
struct am33xx_pinmux_settings irq_conf = pinmux_settings[0];

addr = ioremap(irq_conf.pin_addr, 4);

if (NULL == addr) {
printk(KERN_ALERT RFM12B_DRV_NAME
" : unable to ioremap memory address 0x%x during irq pin muxing.\n",
irq_conf.pin_addr
);

(void)spi_rfm12_cleanup_irq_pin_settings(module_type);

return -EBUSY;
}

switch (module_type) {
case RFM12_TYPE_RF12:
irq_conf.settings |= (2 << 3); // pullup enabled
break;
case RFM12_TYPE_RF69:
irq_conf.settings |= (1 << 3); // no pull
break;
default:
break;
}

iowrite32(irq_conf.settings, addr);
iounmap(addr);

return 0;
}

static int
spi_rfm12_cleanup_pinmux_settings(void)
{
return 0;
}

static int
spi_rfm12_cleanup_irq_pin_settings(rfm12_module_type_t module_type)
{
return 0;
}

#endif // __RFM12_PLAT_BEAGLEBONE_H__
43 changes: 41 additions & 2 deletions platform/plat_raspberrypi.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ struct spi_rfm12_board_config board_configs[NUM_RFM12_BOARDS] = {
static int
spi_rfm12_init_pinmux_settings(void);
static int
spi_rfm12_init_irq_pin_settings(rfm12_module_type_t module_type);
static int
spi_rfm12_cleanup_pinmux_settings(void);
static int
spi_rfm12_cleanup_irq_pin_settings(rfm12_module_type_t module_type);

static int
spi_rfm12_init_pinmux_settings(void)
Expand All @@ -76,6 +80,8 @@ spi_rfm12_init_pinmux_settings(void)

#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_PULL *(gpio+37)
#define GPIO_PULLCLK0 *(gpio+38)

int pin;
u32* gpio = ioremap(0x20200000, SZ_16K);
Expand All @@ -86,20 +92,53 @@ spi_rfm12_init_pinmux_settings(void)
SET_GPIO_ALT(pin, 0);
}

iounmap(gpio);

return 0;
}

static int
spi_rfm12_init_irq_pin_settings(rfm12_module_type_t module_type)
{
u8 pull_mode = 0;

switch (module_type) {
case RFM12_TYPE_RF12:
pull_mode = 0x2; // pullup
break;
case RFM12_TYPE_RF69:
default:
pull_mode = 0; // no pull
break;
}

// irq pin
INP_GPIO(25);
SET_GPIO_ALT(25, 0);

iounmap(gpio);
GPIO_PULL = pull_mode;
udelay(500);
GPIO_PULLCLK0 = (1 << 25);
udelay(500);
GPIO_PULL = 0;
GPIO_PULLCLK0 = 0;

return 0;
}

#undef INP_GPIO
#undef SET_GPIO_ALT
#undef GPIO_PULL
#undef GPIO_PULLCLK0

static int
spi_rfm12_cleanup_pinmux_settings(void)
{
return 0;
}

static int
spi_rfm12_cleanup_pinmux_settings(void)
spi_rfm12_cleanup_irq_pin_settings(rfm12_module_type_t module_type)
{
return 0;
}
Expand Down
33 changes: 32 additions & 1 deletion platform/plat_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ struct spi_rfm12_active_board {
void* irq_data;
struct spi_device* spi_device;
int idx;
rfm12_module_type_t module_type;
struct {
u8 gpio_claimed:1;
u8 irq_claimed:1;
u8 irq_enabled:1;
u8 irq_pinmuxed:1;
} state;
};

Expand Down Expand Up @@ -216,15 +218,36 @@ platform_irq_identifier_for_spi_device(u16 spi_bus, u16 spi_cs)
}

static int
platform_irq_init(void* identifier, u32 irq_trigger, void* rfm12_data)
platform_irq_init(void* identifier, rfm12_module_type_t module_type,
void* rfm12_data)
{
int err;
u32 irq_trigger;
struct spi_rfm12_active_board* brd = (struct spi_rfm12_active_board*)identifier;
struct spi_rfm12_board_config* cfg = &board_configs[brd->idx];

if (brd->state.irq_claimed)
return -EBUSY;

err = spi_rfm12_init_irq_pin_settings(module_type);

if (err) {
return err;
}

brd->state.irq_pinmuxed = 1;
brd->module_type = module_type;

switch(module_type) {
case RFM12_TYPE_RF12:
irq_trigger = IRQF_TRIGGER_FALLING;
break;
case RFM12_TYPE_RF69:
default:
irq_trigger = IRQF_TRIGGER_RISING;
break;
}

err = request_any_context_irq(
brd->irq,
spi_rfm12_irq_handler,
Expand Down Expand Up @@ -267,6 +290,14 @@ platform_irq_cleanup(void* identifier)
brd->irq_data = NULL;
}

if (!err && brd->state.irq_pinmuxed) {
err = spi_rfm12_cleanup_irq_pin_settings(brd->module_type);

if (!err) {
brd->state.irq_pinmuxed = 0;
}
}

return err;
}

Expand Down
3 changes: 2 additions & 1 deletion platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ static void*
platform_irq_identifier_for_spi_device(u16 spi_bus, u16 spi_cs);

static int
platform_irq_init(void* identifier, u32 irq_trigger, void* rfm12_data);
platform_irq_init(void* identifier, rfm12_module_type_t module_type,
void* rfm12_data);

static int
platform_irq_handled(void* identifier);
Expand Down
18 changes: 1 addition & 17 deletions rfm12b.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,6 @@ typedef enum _rfm12_state_t {
RFM12_STATE_SEND_FINISHED = 16
} rfm12_state_t;

typedef enum _rfm12_module_type_t {
RFM12_TYPE_RF12 = 0,
RFM12_TYPE_RF69
} rfm12_module_type_t;

struct rfm12_spi_message {
struct spi_message spi_msg;
struct spi_transfer spi_transfers[4];
Expand Down Expand Up @@ -2424,7 +2419,6 @@ rfm_filop_open(struct inode *inode, struct file *filp)
{
struct rfm12_data* rfm12;
unsigned long flags;
u32 irq_trigger = 0;
int err = -ENXIO, has_irq = 0;

mutex_lock(&device_list_lock);
Expand Down Expand Up @@ -2502,18 +2496,8 @@ rfm_filop_open(struct inode *inode, struct file *filp)
if (0 == err)
rfm_begin_sending_or_receiving(rfm12);

switch (rfm12->module_type) {
case RFM12_TYPE_RF69:
irq_trigger = IRQF_TRIGGER_RISING;
break;
case RFM12_TYPE_RF12:
default:
irq_trigger = IRQF_TRIGGER_FALLING;
break;
}

err = platform_irq_init(
rfm12->irq_identifier, irq_trigger, (void*)rfm12);
rfm12->irq_identifier, rfm12->module_type, (void*)rfm12);
has_irq = (0 == err);
} else
pr_debug("rfm12: nothing for minor %d\n", iminor(inode));
Expand Down
6 changes: 6 additions & 0 deletions rfm12b_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@
#include <linux/version.h>

#if BUILD_MODULE

typedef enum _rfm12_module_type_t {
RFM12_TYPE_RF12 = 0,
RFM12_TYPE_RF69
} rfm12_module_type_t;

#include "platform/platform.h"

#if RFM12B_BOARD==1
Expand Down

0 comments on commit 187c5c4

Please sign in to comment.