2 * vivid-radio-tx.c - radio transmitter support functions.
4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 * This program is free software; you may redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 #include <linux/errno.h>
21 #include <linux/kernel.h>
22 #include <linux/delay.h>
23 #include <linux/videodev2.h>
24 #include <linux/v4l2-dv-timings.h>
25 #include <media/v4l2-common.h>
26 #include <media/v4l2-event.h>
27 #include <media/v4l2-dv-timings.h>
29 #include "vivid-core.h"
30 #include "vivid-ctrls.h"
31 #include "vivid-radio-common.h"
32 #include "vivid-radio-tx.h"
34 ssize_t
vivid_radio_tx_write(struct file
*file
, const char __user
*buf
,
35 size_t size
, loff_t
*offset
)
37 struct vivid_dev
*dev
= video_drvdata(file
);
38 struct v4l2_rds_data
*data
= dev
->rds_gen
.data
;
43 if (dev
->radio_tx_rds_controls
)
46 if (size
< sizeof(*data
))
48 size
= sizeof(*data
) * (size
/ sizeof(*data
));
50 if (mutex_lock_interruptible(&dev
->mutex
))
52 if (dev
->radio_tx_rds_owner
&&
53 file
->private_data
!= dev
->radio_tx_rds_owner
) {
54 mutex_unlock(&dev
->mutex
);
57 dev
->radio_tx_rds_owner
= file
->private_data
;
61 ts
= timespec_sub(ts
, dev
->radio_rds_init_ts
);
62 blk
= ts
.tv_sec
* 100 + ts
.tv_nsec
/ 10000000;
63 blk
= (blk
* VIVID_RDS_GEN_BLOCKS
) / 500;
64 if (blk
- VIVID_RDS_GEN_BLOCKS
>= dev
->radio_tx_rds_last_block
)
65 dev
->radio_tx_rds_last_block
= blk
- VIVID_RDS_GEN_BLOCKS
+ 1;
68 * No data is available if there hasn't been time to get new data,
69 * or if the RDS receiver has been disabled, or if we use the data
70 * from the RDS transmitter and that RDS transmitter has been disabled,
71 * or if the signal quality is too weak.
73 if (blk
== dev
->radio_tx_rds_last_block
||
74 !(dev
->radio_tx_subchans
& V4L2_TUNER_SUB_RDS
)) {
75 mutex_unlock(&dev
->mutex
);
76 if (file
->f_flags
& O_NONBLOCK
)
78 if (msleep_interruptible(20) && signal_pending(current
))
80 if (mutex_lock_interruptible(&dev
->mutex
))
85 for (i
= 0; i
< size
&& blk
> dev
->radio_tx_rds_last_block
;
86 dev
->radio_tx_rds_last_block
++) {
87 unsigned data_blk
= dev
->radio_tx_rds_last_block
% VIVID_RDS_GEN_BLOCKS
;
88 struct v4l2_rds_data rds
;
90 if (copy_from_user(&rds
, buf
+ i
, sizeof(rds
))) {
95 if (!dev
->radio_rds_loop
)
97 if ((rds
.block
& V4L2_RDS_BLOCK_MSK
) == V4L2_RDS_BLOCK_INVALID
||
98 (rds
.block
& V4L2_RDS_BLOCK_ERROR
))
100 rds
.block
&= V4L2_RDS_BLOCK_MSK
;
101 data
[data_blk
] = rds
;
103 mutex_unlock(&dev
->mutex
);
107 unsigned int vivid_radio_tx_poll(struct file
*file
, struct poll_table_struct
*wait
)
109 return POLLOUT
| POLLWRNORM
| v4l2_ctrl_poll(file
, wait
);
112 int vidioc_g_modulator(struct file
*file
, void *fh
, struct v4l2_modulator
*a
)
114 struct vivid_dev
*dev
= video_drvdata(file
);
119 strlcpy(a
->name
, "AM/FM/SW Transmitter", sizeof(a
->name
));
120 a
->capability
= V4L2_TUNER_CAP_LOW
| V4L2_TUNER_CAP_STEREO
|
121 V4L2_TUNER_CAP_FREQ_BANDS
| V4L2_TUNER_CAP_RDS
|
122 (dev
->radio_tx_rds_controls
?
123 V4L2_TUNER_CAP_RDS_CONTROLS
:
124 V4L2_TUNER_CAP_RDS_BLOCK_IO
);
125 a
->rangelow
= AM_FREQ_RANGE_LOW
;
126 a
->rangehigh
= FM_FREQ_RANGE_HIGH
;
127 a
->txsubchans
= dev
->radio_tx_subchans
;
131 int vidioc_s_modulator(struct file
*file
, void *fh
, const struct v4l2_modulator
*a
)
133 struct vivid_dev
*dev
= video_drvdata(file
);
137 if (a
->txsubchans
& ~0x13)
139 dev
->radio_tx_subchans
= a
->txsubchans
;