162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Framework for ISA radio drivers. 462306a36Sopenharmony_ci * This takes care of all the V4L2 scaffolding, allowing the ISA drivers 562306a36Sopenharmony_ci * to concentrate on the actual hardware operation. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef _RADIO_ISA_H_ 1162306a36Sopenharmony_ci#define _RADIO_ISA_H_ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/isa.h> 1462306a36Sopenharmony_ci#include <linux/pnp.h> 1562306a36Sopenharmony_ci#include <linux/videodev2.h> 1662306a36Sopenharmony_ci#include <media/v4l2-device.h> 1762306a36Sopenharmony_ci#include <media/v4l2-ctrls.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistruct radio_isa_driver; 2062306a36Sopenharmony_cistruct radio_isa_ops; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* Core structure for radio ISA cards */ 2362306a36Sopenharmony_cistruct radio_isa_card { 2462306a36Sopenharmony_ci const struct radio_isa_driver *drv; 2562306a36Sopenharmony_ci struct v4l2_device v4l2_dev; 2662306a36Sopenharmony_ci struct v4l2_ctrl_handler hdl; 2762306a36Sopenharmony_ci struct video_device vdev; 2862306a36Sopenharmony_ci struct mutex lock; 2962306a36Sopenharmony_ci const struct radio_isa_ops *ops; 3062306a36Sopenharmony_ci struct { /* mute/volume cluster */ 3162306a36Sopenharmony_ci struct v4l2_ctrl *mute; 3262306a36Sopenharmony_ci struct v4l2_ctrl *volume; 3362306a36Sopenharmony_ci }; 3462306a36Sopenharmony_ci /* I/O port */ 3562306a36Sopenharmony_ci int io; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci /* Card is in stereo audio mode */ 3862306a36Sopenharmony_ci bool stereo; 3962306a36Sopenharmony_ci /* Current frequency */ 4062306a36Sopenharmony_ci u32 freq; 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistruct radio_isa_ops { 4462306a36Sopenharmony_ci /* Allocate and initialize a radio_isa_card struct */ 4562306a36Sopenharmony_ci struct radio_isa_card *(*alloc)(void); 4662306a36Sopenharmony_ci /* Probe whether a card is present at the given port */ 4762306a36Sopenharmony_ci bool (*probe)(struct radio_isa_card *isa, int io); 4862306a36Sopenharmony_ci /* Special card initialization can be done here, this is called after 4962306a36Sopenharmony_ci * the standard controls are registered, but before they are setup, 5062306a36Sopenharmony_ci * thus allowing drivers to add their own controls here. */ 5162306a36Sopenharmony_ci int (*init)(struct radio_isa_card *isa); 5262306a36Sopenharmony_ci /* Set mute and volume. */ 5362306a36Sopenharmony_ci int (*s_mute_volume)(struct radio_isa_card *isa, bool mute, int volume); 5462306a36Sopenharmony_ci /* Set frequency */ 5562306a36Sopenharmony_ci int (*s_frequency)(struct radio_isa_card *isa, u32 freq); 5662306a36Sopenharmony_ci /* Set stereo/mono audio mode */ 5762306a36Sopenharmony_ci int (*s_stereo)(struct radio_isa_card *isa, bool stereo); 5862306a36Sopenharmony_ci /* Get rxsubchans value for VIDIOC_G_TUNER */ 5962306a36Sopenharmony_ci u32 (*g_rxsubchans)(struct radio_isa_card *isa); 6062306a36Sopenharmony_ci /* Get the signal strength for VIDIOC_G_TUNER */ 6162306a36Sopenharmony_ci u32 (*g_signal)(struct radio_isa_card *isa); 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* Top level structure needed to instantiate the cards */ 6562306a36Sopenharmony_cistruct radio_isa_driver { 6662306a36Sopenharmony_ci struct isa_driver driver; 6762306a36Sopenharmony_ci#ifdef CONFIG_PNP 6862306a36Sopenharmony_ci struct pnp_driver pnp_driver; 6962306a36Sopenharmony_ci#endif 7062306a36Sopenharmony_ci const struct radio_isa_ops *ops; 7162306a36Sopenharmony_ci /* The module_param_array with the specified I/O ports */ 7262306a36Sopenharmony_ci int *io_params; 7362306a36Sopenharmony_ci /* The module_param_array with the radio_nr values */ 7462306a36Sopenharmony_ci int *radio_nr_params; 7562306a36Sopenharmony_ci /* Whether we should probe for possible cards */ 7662306a36Sopenharmony_ci bool probe; 7762306a36Sopenharmony_ci /* The list of possible I/O ports */ 7862306a36Sopenharmony_ci const int *io_ports; 7962306a36Sopenharmony_ci /* The size of that list */ 8062306a36Sopenharmony_ci int num_of_io_ports; 8162306a36Sopenharmony_ci /* The region size to request */ 8262306a36Sopenharmony_ci unsigned region_size; 8362306a36Sopenharmony_ci /* The name of the card */ 8462306a36Sopenharmony_ci const char *card; 8562306a36Sopenharmony_ci /* Card can capture stereo audio */ 8662306a36Sopenharmony_ci bool has_stereo; 8762306a36Sopenharmony_ci /* The maximum volume for the volume control. If 0, then there 8862306a36Sopenharmony_ci is no volume control possible. */ 8962306a36Sopenharmony_ci int max_volume; 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ciint radio_isa_match(struct device *pdev, unsigned int dev); 9362306a36Sopenharmony_ciint radio_isa_probe(struct device *pdev, unsigned int dev); 9462306a36Sopenharmony_civoid radio_isa_remove(struct device *pdev, unsigned int dev); 9562306a36Sopenharmony_ci#ifdef CONFIG_PNP 9662306a36Sopenharmony_ciint radio_isa_pnp_probe(struct pnp_dev *dev, 9762306a36Sopenharmony_ci const struct pnp_device_id *dev_id); 9862306a36Sopenharmony_civoid radio_isa_pnp_remove(struct pnp_dev *dev); 9962306a36Sopenharmony_ci#endif 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#endif 102