staging: comedi: drivers: use comedi_dio_insn_config() for simple cases
Convert the drivers with simple, per channel programmable i/o, to use the comedi_dio_insn_config() helper function. All of these pass a 'mask' of '0' to comedi_dio_insn_config() this causes the per channel mask to be used to configure the i/o direction. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f3508b2294
commit
ddf62f2c7b
@ -3510,31 +3510,20 @@ static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
|
||||
static int dio_60xx_config_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
struct pcidas64_private *devpriv = dev->private;
|
||||
unsigned int mask;
|
||||
int ret;
|
||||
|
||||
mask = 1 << CR_CHAN(insn->chanspec);
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return 2;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
writeb(s->io_bits,
|
||||
devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
|
||||
|
||||
return 1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
|
@ -158,27 +158,16 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev,
|
||||
|
||||
static int ni_670x_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
struct ni_670x_private *devpriv = dev->private;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
int ret;
|
||||
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= 1 << chan;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~(1 << chan);
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
|
||||
|
||||
return insn->n;
|
||||
|
@ -90,21 +90,17 @@ static int daq700_dio_insn_bits(struct comedi_device *dev,
|
||||
|
||||
static int daq700_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned int chan = 1 << CR_CHAN(insn->chanspec);
|
||||
int ret;
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
break;
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & chan) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* The DIO channels are not configurable, fix the io_bits */
|
||||
s->io_bits = 0x00ff;
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
@ -3528,37 +3528,21 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
static int ni_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
struct ni_private *devpriv = dev->private;
|
||||
int ret;
|
||||
|
||||
#ifdef DEBUG_DIO
|
||||
printk("ni_dio_insn_config() chan=%d io=%d\n",
|
||||
CR_CHAN(insn->chanspec), data[0]);
|
||||
#endif
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= 1 << CR_CHAN(insn->chanspec);
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->
|
||||
io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
|
||||
COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
|
||||
devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
|
||||
devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
|
||||
|
||||
return 1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int ni_dio_insn_bits(struct comedi_device *dev,
|
||||
@ -3596,32 +3580,15 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
|
||||
unsigned int *data)
|
||||
{
|
||||
struct ni_private *devpriv __maybe_unused = dev->private;
|
||||
int ret;
|
||||
|
||||
#ifdef DEBUG_DIO
|
||||
printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
|
||||
CR_CHAN(insn->chanspec), data[0]);
|
||||
#endif
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= 1 << CR_CHAN(insn->chanspec);
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->
|
||||
io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
|
||||
COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ni_writel(s->io_bits, M_Offset_DIO_Direction);
|
||||
|
||||
return 1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
|
||||
|
@ -640,32 +640,19 @@ static void debug_int(struct comedi_device *dev)
|
||||
|
||||
static int ni_pcidio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
struct nidio96_private *devpriv = dev->private;
|
||||
int ret;
|
||||
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (insn->n != 1)
|
||||
return -EINVAL;
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= 1 << CR_CHAN(insn->chanspec);
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->
|
||||
io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
|
||||
COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
|
||||
|
||||
return 1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int ni_pcidio_insn_bits(struct comedi_device *dev,
|
||||
|
@ -310,68 +310,27 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev,
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/* The input or output configuration of each digital line is
|
||||
* configured by a special insn_config instruction. chanspec
|
||||
* contains the channel to be changed, and data[0] contains the
|
||||
* value COMEDI_INPUT or COMEDI_OUTPUT. */
|
||||
static int pcmmio_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
|
||||
chan % 8;
|
||||
unsigned long ioaddr;
|
||||
unsigned char byte;
|
||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||
int byte_no = chan / 8;
|
||||
int bit_no = chan % 8;
|
||||
int ret;
|
||||
|
||||
/* Compute ioaddr for this channel */
|
||||
ioaddr = subpriv->iobases[byte_no];
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* NOTE:
|
||||
writing a 0 an IO channel's bit sets the channel to INPUT
|
||||
and pulls the line high as well
|
||||
if (data[0] == INSN_CONFIG_DIO_INPUT) {
|
||||
unsigned long ioaddr = subpriv->iobases[byte_no];
|
||||
unsigned char val;
|
||||
|
||||
writing a 1 to an IO channel's bit pulls the line low
|
||||
|
||||
All channels are implicitly always in OUTPUT mode -- but when
|
||||
they are high they can be considered to be in INPUT mode..
|
||||
|
||||
Thus, we only force channels low if the config request was INPUT,
|
||||
otherwise we do nothing to the hardware. */
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
/* save to io_bits -- don't actually do anything since
|
||||
all input channels are also output channels... */
|
||||
s->io_bits |= 1 << chan;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
/* write a 0 to the actual register representing the channel
|
||||
to set it to 'input'. 0 means "float high". */
|
||||
byte = inb(ioaddr);
|
||||
byte &= ~(1 << bit_no);
|
||||
/**< set input channel to '0' */
|
||||
|
||||
/*
|
||||
* write out byte -- this is the only time we actually affect
|
||||
* the hardware as all channels are implicitly output
|
||||
* -- but input channels are set to float-high
|
||||
*/
|
||||
outb(byte, ioaddr);
|
||||
|
||||
/* save to io_bits */
|
||||
s->io_bits &= ~(1 << chan);
|
||||
break;
|
||||
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
/* retrieve from shadow register */
|
||||
data[1] =
|
||||
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
val = inb(ioaddr);
|
||||
val &= ~(1 << bit_no);
|
||||
outb(val, ioaddr);
|
||||
}
|
||||
|
||||
return insn->n;
|
||||
|
@ -233,27 +233,19 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev,
|
||||
|
||||
static int pcmuio_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
|
||||
int asic = s->index / 2;
|
||||
int port = (s->index % 2) ? 3 : 0;
|
||||
int ret;
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= chan_mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~chan_mask;
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (data[0] == INSN_CONFIG_DIO_INPUT)
|
||||
pcmuio_write(dev, s->io_bits, asic, 0, port);
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & chan_mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
@ -1238,23 +1238,11 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
|
||||
unsigned int *data)
|
||||
{
|
||||
struct rtd_private *devpriv = dev->private;
|
||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||
unsigned int mask = 1 << chan;
|
||||
int ret;
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* TODO support digital match interrupts and strobes */
|
||||
|
||||
|
@ -1662,24 +1662,12 @@ static int s626_dio_insn_config(struct comedi_device *dev,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned long group = (unsigned long)s->private;
|
||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||
unsigned int mask = 1 << chan;
|
||||
int ret;
|
||||
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
case COMEDI_INPUT:
|
||||
s->io_bits &= ~mask;
|
||||
break;
|
||||
case COMEDI_OUTPUT:
|
||||
s->io_bits |= mask;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
|
||||
|
||||
return insn->n;
|
||||
|
@ -93,68 +93,48 @@ static int dnp_dio_insn_bits(struct comedi_device *dev,
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Configure the direction of the bidirectional digital i/o pins. chanspec */
|
||||
/* contains the channel to be changed and data[0] contains either */
|
||||
/* COMEDI_INPUT or COMEDI_OUTPUT. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int dnp_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||
unsigned int mask;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
u8 register_buffer;
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* reduces chanspec to lower 16 bits */
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
/* Test: which port does the channel belong to? */
|
||||
|
||||
/* We have to pay attention with port C: this is the meaning of PCMR: */
|
||||
/* Bit in PCMR: 7 6 5 4 3 2 1 0 */
|
||||
/* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */
|
||||
|
||||
if ((chan >= 0) && (chan <= 7)) {
|
||||
/* this is port A */
|
||||
if (chan < 8) { /* Port A */
|
||||
mask = 1 << chan;
|
||||
outb(PAMR, CSCIR);
|
||||
} else if ((chan >= 8) && (chan <= 15)) {
|
||||
/* this is port B */
|
||||
chan -= 8;
|
||||
} else if (chan < 16) { /* Port B */
|
||||
mask = 1 << (chan - 8);
|
||||
outb(PBMR, CSCIR);
|
||||
} else if ((chan >= 16) && (chan <= 19)) {
|
||||
/* this is port C; multiplication with 2 brings bits into */
|
||||
/* correct position for PCMR! */
|
||||
chan -= 16;
|
||||
chan *= 2;
|
||||
} else { /* Port C */
|
||||
/*
|
||||
* We have to pay attention with port C.
|
||||
* This is the meaning of PCMR:
|
||||
* Bit in PCMR: 7 6 5 4 3 2 1 0
|
||||
* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch
|
||||
*
|
||||
* Multiplication by 2 brings bits into correct position
|
||||
* for PCMR!
|
||||
*/
|
||||
mask = 1 << ((chan - 16) * 2);
|
||||
outb(PCMR, CSCIR);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* read 'old' direction of the port and set bits (out=1, in=0) */
|
||||
register_buffer = inb(CSCDR);
|
||||
val = inb(CSCDR);
|
||||
if (data[0] == COMEDI_OUTPUT)
|
||||
register_buffer |= (1 << chan);
|
||||
val |= mask;
|
||||
else
|
||||
register_buffer &= ~(1 << chan);
|
||||
val &= ~mask;
|
||||
outb(val, CSCDR);
|
||||
|
||||
outb(register_buffer, CSCDR);
|
||||
|
||||
return 1;
|
||||
return insn->n;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1113,22 +1113,11 @@ static int usbdux_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned int mask = 1 << CR_CHAN(insn->chanspec);
|
||||
int ret;
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* We don't tell the firmware here as it would take 8 frames
|
||||
|
@ -1040,23 +1040,11 @@ static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||
unsigned int mask = 1 << chan;
|
||||
int ret;
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~mask;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* We don't tell the firmware here as it would take 8 frames
|
||||
|
Loading…
Reference in New Issue
Block a user