Skip to content

Commit dd23943

Browse files
committed
misc: rp1-pio: Add FIFO-related methods
Add support for querying the FIFO status and clearing the TX FIFO. Signed-off-by: Phil Elwell <[email protected]>
1 parent 57b528e commit dd23943

File tree

4 files changed

+128
-1
lines changed

4 files changed

+128
-1
lines changed

Diff for: drivers/misc/rp1-fw-pio.h

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ enum rp1_pio_ops {
4747
READ_HW, // src address, len -> data bytes
4848
WRITE_HW, // dst address, data
4949

50+
PIO_SM_FIFO_STATE, // u16 sm, u8 tx -> u16 level, u8 empty, u8 full
51+
PIO_SM_DRAIN_TX, // u16 sm
52+
5053
PIO_COUNT
5154
};
5255

Diff for: drivers/misc/rp1-pio.c

+24
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,28 @@ int rp1_pio_sm_set_dmactrl(struct rp1_pio_client *client, void *param)
476476
}
477477
EXPORT_SYMBOL_GPL(rp1_pio_sm_set_dmactrl);
478478

479+
int rp1_pio_sm_fifo_state(struct rp1_pio_client *client, void *param)
480+
{
481+
struct rp1_pio_sm_fifo_state_args *args = param;
482+
const int level_offset = offsetof(struct rp1_pio_sm_fifo_state_args, level);
483+
int ret;
484+
485+
ret = rp1_pio_message_resp(client->pio, PIO_SM_FIFO_STATE, args, sizeof(*args),
486+
&args->level, NULL, sizeof(*args) - level_offset);
487+
if (ret >= 0)
488+
return level_offset + ret;
489+
return ret;
490+
}
491+
EXPORT_SYMBOL_GPL(rp1_pio_sm_fifo_state);
492+
493+
int rp1_pio_sm_drain_tx(struct rp1_pio_client *client, void *param)
494+
{
495+
struct rp1_pio_sm_clear_fifos_args *args = param;
496+
497+
return rp1_pio_message(client->pio, PIO_SM_DRAIN_TX, args, sizeof(*args));
498+
}
499+
EXPORT_SYMBOL_GPL(rp1_pio_sm_drain_tx);
500+
479501
int rp1_pio_gpio_init(struct rp1_pio_client *client, void *param)
480502
{
481503
struct rp1_gpio_init_args *args = param;
@@ -848,6 +870,8 @@ struct handler_info {
848870
HANDLER(SM_PUT, sm_put),
849871
HANDLER(SM_GET, sm_get),
850872
HANDLER(SM_SET_DMACTRL, sm_set_dmactrl),
873+
HANDLER(SM_FIFO_STATE, sm_fifo_state),
874+
HANDLER(SM_DRAIN_TX, sm_drain_tx),
851875

852876
HANDLER(GPIO_INIT, gpio_init),
853877
HANDLER(GPIO_SET_FUNCTION, gpio_set_function),

Diff for: include/linux/pio_rp1.h

+89
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ int rp1_pio_sm_enable_sync(struct rp1_pio_client *client, void *param);
200200
int rp1_pio_sm_put(struct rp1_pio_client *client, void *param);
201201
int rp1_pio_sm_get(struct rp1_pio_client *client, void *param);
202202
int rp1_pio_sm_set_dmactrl(struct rp1_pio_client *client, void *param);
203+
int rp1_pio_sm_fifo_state(struct rp1_pio_client *client, void *param);
204+
int rp1_pio_sm_drain_tx(struct rp1_pio_client *client, void *param);
203205
int rp1_pio_gpio_init(struct rp1_pio_client *client, void *param);
204206
int rp1_pio_gpio_set_function(struct rp1_pio_client *client, void *param);
205207
int rp1_pio_gpio_set_pulls(struct rp1_pio_client *client, void *param);
@@ -551,6 +553,15 @@ static inline int pio_sm_set_dmactrl(struct rp1_pio_client *client, uint sm, boo
551553
return rp1_pio_sm_set_dmactrl(client, &args);
552554
};
553555

556+
static inline int pio_sm_drain_tx_fifo(struct rp1_pio_client *client, uint sm)
557+
{
558+
struct rp1_pio_sm_clear_fifos_args args = { .sm = sm };
559+
560+
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
561+
return -EINVAL;
562+
return rp1_pio_sm_drain_tx(client, &args);
563+
};
564+
554565
static inline int pio_sm_put(struct rp1_pio_client *client, uint sm, uint32_t data)
555566
{
556567
struct rp1_pio_sm_put_args args = { .sm = (uint16_t)sm, .blocking = false, .data = data };
@@ -587,6 +598,84 @@ static inline uint32_t pio_sm_get_blocking(struct rp1_pio_client *client, uint s
587598
return args.data;
588599
}
589600

601+
static inline int pio_sm_is_rx_fifo_empty(struct rp1_pio_client *client, uint sm)
602+
{
603+
struct rp1_pio_sm_fifo_state_args args = { .sm = sm, .tx = false };
604+
int ret;
605+
606+
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
607+
return -EINVAL;
608+
ret = rp1_pio_sm_fifo_state(client, &args);
609+
if (ret == sizeof(args))
610+
ret = args.empty;
611+
return ret;
612+
};
613+
614+
static inline int pio_sm_is_rx_fifo_full(struct rp1_pio_client *client, uint sm)
615+
{
616+
struct rp1_pio_sm_fifo_state_args args = { .sm = sm, .tx = false };
617+
int ret;
618+
619+
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
620+
return -EINVAL;
621+
ret = rp1_pio_sm_fifo_state(client, &args);
622+
if (ret == sizeof(args))
623+
ret = args.full;
624+
return ret;
625+
};
626+
627+
static inline int pio_sm_rx_fifo_level(struct rp1_pio_client *client, uint sm)
628+
{
629+
struct rp1_pio_sm_fifo_state_args args = { .sm = sm, .tx = false };
630+
int ret;
631+
632+
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
633+
return -EINVAL;
634+
ret = rp1_pio_sm_fifo_state(client, &args);
635+
if (ret == sizeof(args))
636+
ret = args.level;
637+
return ret;
638+
};
639+
640+
static inline int pio_sm_is_tx_fifo_empty(struct rp1_pio_client *client, uint sm)
641+
{
642+
struct rp1_pio_sm_fifo_state_args args = { .sm = sm, .tx = true };
643+
int ret;
644+
645+
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
646+
return -EINVAL;
647+
ret = rp1_pio_sm_fifo_state(client, &args);
648+
if (ret == sizeof(args))
649+
ret = args.empty;
650+
return ret;
651+
};
652+
653+
static inline int pio_sm_is_tx_fifo_full(struct rp1_pio_client *client, uint sm)
654+
{
655+
struct rp1_pio_sm_fifo_state_args args = { .sm = sm, .tx = true };
656+
int ret;
657+
658+
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
659+
return -EINVAL;
660+
ret = rp1_pio_sm_fifo_state(client, &args);
661+
if (ret == sizeof(args))
662+
ret = args.full;
663+
return ret;
664+
};
665+
666+
static inline int pio_sm_tx_fifo_level(struct rp1_pio_client *client, uint sm)
667+
{
668+
struct rp1_pio_sm_fifo_state_args args = { .sm = sm, .tx = true };
669+
int ret;
670+
671+
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
672+
return -EINVAL;
673+
ret = rp1_pio_sm_fifo_state(client, &args);
674+
if (ret == sizeof(args))
675+
ret = args.level;
676+
return ret;
677+
};
678+
590679
static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint out_count)
591680
{
592681
if (bad_params_if(NULL, out_base >= RP1_PIO_GPIO_COUNT ||

Diff for: include/uapi/misc/rp1_pio_if.h

+12-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ struct rp1_pio_sm_get_args {
114114
uint16_t sm;
115115
uint8_t blocking;
116116
uint8_t rsvd;
117-
uint32_t data; /* IN/OUT */
117+
uint32_t data; /* OUT */
118118
};
119119

120120
struct rp1_pio_sm_set_dmactrl_args {
@@ -124,6 +124,15 @@ struct rp1_pio_sm_set_dmactrl_args {
124124
uint32_t ctrl;
125125
};
126126

127+
struct rp1_pio_sm_fifo_state_args {
128+
uint16_t sm;
129+
uint8_t tx;
130+
uint8_t rsvd;
131+
uint16_t level; /* OUT */
132+
uint8_t empty; /* OUT */
133+
uint8_t full; /* OUT */
134+
};
135+
127136
struct rp1_gpio_init_args {
128137
uint16_t gpio;
129138
};
@@ -195,6 +204,8 @@ struct rp1_access_hw_args {
195204
#define PIO_IOC_SM_PUT _IOW(PIO_IOC_MAGIC, 41, struct rp1_pio_sm_put_args)
196205
#define PIO_IOC_SM_GET _IOWR(PIO_IOC_MAGIC, 42, struct rp1_pio_sm_get_args)
197206
#define PIO_IOC_SM_SET_DMACTRL _IOW(PIO_IOC_MAGIC, 43, struct rp1_pio_sm_set_dmactrl_args)
207+
#define PIO_IOC_SM_FIFO_STATE _IOW(PIO_IOC_MAGIC, 44, struct rp1_pio_sm_fifo_state_args)
208+
#define PIO_IOC_SM_DRAIN_TX _IOW(PIO_IOC_MAGIC, 45, struct rp1_pio_sm_clear_fifos_args)
198209

199210
#define PIO_IOC_GPIO_INIT _IOW(PIO_IOC_MAGIC, 50, struct rp1_gpio_init_args)
200211
#define PIO_IOC_GPIO_SET_FUNCTION _IOW(PIO_IOC_MAGIC, 51, struct rp1_gpio_set_function_args)

0 commit comments

Comments
 (0)