18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Framework for ISA radio drivers. 48c2ecf20Sopenharmony_ci * This takes care of all the V4L2 scaffolding, allowing the ISA drivers 58c2ecf20Sopenharmony_ci * to concentrate on the actual hardware operation. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef _RADIO_ISA_H_ 118c2ecf20Sopenharmony_ci#define _RADIO_ISA_H_ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/isa.h> 148c2ecf20Sopenharmony_ci#include <linux/pnp.h> 158c2ecf20Sopenharmony_ci#include <linux/videodev2.h> 168c2ecf20Sopenharmony_ci#include <media/v4l2-device.h> 178c2ecf20Sopenharmony_ci#include <media/v4l2-ctrls.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistruct radio_isa_driver; 208c2ecf20Sopenharmony_cistruct radio_isa_ops; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* Core structure for radio ISA cards */ 238c2ecf20Sopenharmony_cistruct radio_isa_card { 248c2ecf20Sopenharmony_ci const struct radio_isa_driver *drv; 258c2ecf20Sopenharmony_ci struct v4l2_device v4l2_dev; 268c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler hdl; 278c2ecf20Sopenharmony_ci struct video_device vdev; 288c2ecf20Sopenharmony_ci struct mutex lock; 298c2ecf20Sopenharmony_ci const struct radio_isa_ops *ops; 308c2ecf20Sopenharmony_ci struct { /* mute/volume cluster */ 318c2ecf20Sopenharmony_ci struct v4l2_ctrl *mute; 328c2ecf20Sopenharmony_ci struct v4l2_ctrl *volume; 338c2ecf20Sopenharmony_ci }; 348c2ecf20Sopenharmony_ci /* I/O port */ 358c2ecf20Sopenharmony_ci int io; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci /* Card is in stereo audio mode */ 388c2ecf20Sopenharmony_ci bool stereo; 398c2ecf20Sopenharmony_ci /* Current frequency */ 408c2ecf20Sopenharmony_ci u32 freq; 418c2ecf20Sopenharmony_ci}; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistruct radio_isa_ops { 448c2ecf20Sopenharmony_ci /* Allocate and initialize a radio_isa_card struct */ 458c2ecf20Sopenharmony_ci struct radio_isa_card *(*alloc)(void); 468c2ecf20Sopenharmony_ci /* Probe whether a card is present at the given port */ 478c2ecf20Sopenharmony_ci bool (*probe)(struct radio_isa_card *isa, int io); 488c2ecf20Sopenharmony_ci /* Special card initialization can be done here, this is called after 498c2ecf20Sopenharmony_ci * the standard controls are registered, but before they are setup, 508c2ecf20Sopenharmony_ci * thus allowing drivers to add their own controls here. */ 518c2ecf20Sopenharmony_ci int (*init)(struct radio_isa_card *isa); 528c2ecf20Sopenharmony_ci /* Set mute and volume. */ 538c2ecf20Sopenharmony_ci int (*s_mute_volume)(struct radio_isa_card *isa, bool mute, int volume); 548c2ecf20Sopenharmony_ci /* Set frequency */ 558c2ecf20Sopenharmony_ci int (*s_frequency)(struct radio_isa_card *isa, u32 freq); 568c2ecf20Sopenharmony_ci /* Set stereo/mono audio mode */ 578c2ecf20Sopenharmony_ci int (*s_stereo)(struct radio_isa_card *isa, bool stereo); 588c2ecf20Sopenharmony_ci /* Get rxsubchans value for VIDIOC_G_TUNER */ 598c2ecf20Sopenharmony_ci u32 (*g_rxsubchans)(struct radio_isa_card *isa); 608c2ecf20Sopenharmony_ci /* Get the signal strength for VIDIOC_G_TUNER */ 618c2ecf20Sopenharmony_ci u32 (*g_signal)(struct radio_isa_card *isa); 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/* Top level structure needed to instantiate the cards */ 658c2ecf20Sopenharmony_cistruct radio_isa_driver { 668c2ecf20Sopenharmony_ci struct isa_driver driver; 678c2ecf20Sopenharmony_ci#ifdef CONFIG_PNP 688c2ecf20Sopenharmony_ci struct pnp_driver pnp_driver; 698c2ecf20Sopenharmony_ci#endif 708c2ecf20Sopenharmony_ci const struct radio_isa_ops *ops; 718c2ecf20Sopenharmony_ci /* The module_param_array with the specified I/O ports */ 728c2ecf20Sopenharmony_ci int *io_params; 738c2ecf20Sopenharmony_ci /* The module_param_array with the radio_nr values */ 748c2ecf20Sopenharmony_ci int *radio_nr_params; 758c2ecf20Sopenharmony_ci /* Whether we should probe for possible cards */ 768c2ecf20Sopenharmony_ci bool probe; 778c2ecf20Sopenharmony_ci /* The list of possible I/O ports */ 788c2ecf20Sopenharmony_ci const int *io_ports; 798c2ecf20Sopenharmony_ci /* The size of that list */ 808c2ecf20Sopenharmony_ci int num_of_io_ports; 818c2ecf20Sopenharmony_ci /* The region size to request */ 828c2ecf20Sopenharmony_ci unsigned region_size; 838c2ecf20Sopenharmony_ci /* The name of the card */ 848c2ecf20Sopenharmony_ci const char *card; 858c2ecf20Sopenharmony_ci /* Card can capture stereo audio */ 868c2ecf20Sopenharmony_ci bool has_stereo; 878c2ecf20Sopenharmony_ci /* The maximum volume for the volume control. If 0, then there 888c2ecf20Sopenharmony_ci is no volume control possible. */ 898c2ecf20Sopenharmony_ci int max_volume; 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ciint radio_isa_match(struct device *pdev, unsigned int dev); 938c2ecf20Sopenharmony_ciint radio_isa_probe(struct device *pdev, unsigned int dev); 948c2ecf20Sopenharmony_ciint radio_isa_remove(struct device *pdev, unsigned int dev); 958c2ecf20Sopenharmony_ci#ifdef CONFIG_PNP 968c2ecf20Sopenharmony_ciint radio_isa_pnp_probe(struct pnp_dev *dev, 978c2ecf20Sopenharmony_ci const struct pnp_device_id *dev_id); 988c2ecf20Sopenharmony_civoid radio_isa_pnp_remove(struct pnp_dev *dev); 998c2ecf20Sopenharmony_ci#endif 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci#endif 102