Eric Laurent | 699ce29 | 2015-02-10 18:30:42 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #ifndef ANDROID_RADIO_H |
| 18 | #define ANDROID_RADIO_H |
| 19 | |
| 20 | #include <stdbool.h> |
| 21 | #include <stdint.h> |
| 22 | #include <stdio.h> |
| 23 | #include <sys/cdefs.h> |
| 24 | #include <sys/types.h> |
| 25 | |
| 26 | |
| 27 | #define RADIO_NUM_BANDS_MAX 16 |
| 28 | #define RADIO_NUM_SPACINGS_MAX 16 |
| 29 | #define RADIO_STRING_LEN_MAX 128 |
| 30 | |
| 31 | /* |
| 32 | * Radio hardware module class. A given radio hardware module HAL is of one class |
| 33 | * only. The platform can not have more than one hardware module of each class. |
| 34 | * Current version of the framework only supports RADIO_CLASS_AM_FM. |
| 35 | */ |
| 36 | typedef enum { |
| 37 | RADIO_CLASS_AM_FM = 0, /* FM (including HD radio) and AM */ |
| 38 | RADIO_CLASS_SAT = 1, /* Satellite Radio */ |
| 39 | RADIO_CLASS_DT = 2, /* Digital Radio (DAB) */ |
| 40 | } radio_class_t; |
| 41 | |
| 42 | /* value for field "type" of radio band described in struct radio_hal_band_config */ |
| 43 | typedef enum { |
| 44 | RADIO_BAND_AM = 0, /* Amplitude Modulation band: LW, MW, SW */ |
| 45 | RADIO_BAND_FM = 1, /* Frequency Modulation band: FM */ |
| 46 | RADIO_BAND_FM_HD = 2, /* FM HD Radio / DRM (IBOC) */ |
| 47 | RADIO_BAND_AM_HD = 3, /* AM HD Radio / DRM (IBOC) */ |
| 48 | } radio_band_t; |
| 49 | |
| 50 | /* RDS variant implemented. A struct radio_hal_fm_band_config can list none or several. */ |
| 51 | enum { |
| 52 | RADIO_RDS_NONE = 0x0, |
| 53 | RADIO_RDS_WORLD = 0x01, |
| 54 | RADIO_RDS_US = 0x02, |
| 55 | }; |
| 56 | typedef unsigned int radio_rds_t; |
| 57 | |
| 58 | /* FM deemphasis variant implemented. A struct radio_hal_fm_band_config can list one or more. */ |
| 59 | enum { |
| 60 | RADIO_DEEMPHASIS_50 = 0x1, |
| 61 | RADIO_DEEMPHASIS_75 = 0x2, |
| 62 | }; |
| 63 | typedef unsigned int radio_deemphasis_t; |
| 64 | |
| 65 | /* Region a particular radio band configuration corresponds to. Not used at the HAL. |
| 66 | * Derived by the framework when converting the band descriptors retrieved from the HAL to |
| 67 | * individual band descriptors for each supported region. */ |
| 68 | typedef enum { |
| 69 | RADIO_REGION_NONE = -1, |
| 70 | RADIO_REGION_ITU_1 = 0, |
| 71 | RADIO_REGION_ITU_2 = 1, |
| 72 | RADIO_REGION_OIRT = 2, |
| 73 | RADIO_REGION_JAPAN = 3, |
| 74 | RADIO_REGION_KOREA = 4, |
| 75 | } radio_region_t; |
| 76 | |
| 77 | /* scanning direction for scan() and step() tuner APIs */ |
| 78 | typedef enum { |
| 79 | RADIO_DIRECTION_UP, |
| 80 | RADIO_DIRECTION_DOWN |
| 81 | } radio_direction_t; |
| 82 | |
| 83 | /* unique handle allocated to a radio module */ |
| 84 | typedef unsigned int radio_handle_t; |
| 85 | |
| 86 | /* Opaque meta data structure used by radio meta data API (see system/radio_metadata.h) */ |
| 87 | typedef struct radio_medtadata radio_metadata_t; |
| 88 | |
| 89 | |
| 90 | /* Additional attributes for an FM band configuration */ |
| 91 | typedef struct radio_hal_fm_band_config { |
| 92 | radio_deemphasis_t deemphasis; /* deemphasis variant */ |
| 93 | bool stereo; /* stereo supported */ |
| 94 | radio_rds_t rds; /* RDS variants supported */ |
| 95 | bool ta; /* Traffic Announcement supported */ |
| 96 | bool af; /* Alternate Frequency supported */ |
Sanket Agarwal | 2ccc52c | 2015-10-16 14:37:01 -0700 | [diff] [blame] | 97 | bool ea; /* Emergency announcements supported */ |
Eric Laurent | 699ce29 | 2015-02-10 18:30:42 -0800 | [diff] [blame] | 98 | } radio_hal_fm_band_config_t; |
| 99 | |
| 100 | /* Additional attributes for an AM band configuration */ |
| 101 | typedef struct radio_hal_am_band_config { |
| 102 | bool stereo; /* stereo supported */ |
| 103 | } radio_hal_am_band_config_t; |
| 104 | |
| 105 | /* Radio band configuration. Describes a given band supported by the radio module. |
| 106 | * The HAL can expose only one band per type with the the maximum range supported and all options. |
| 107 | * THe framework will derive the actual regions were this module can operate and expose separate |
| 108 | * band configurations for applications to chose from. */ |
| 109 | typedef struct radio_hal_band_config { |
| 110 | radio_band_t type; |
| 111 | bool antenna_connected; |
| 112 | unsigned int lower_limit; |
| 113 | unsigned int upper_limit; |
| 114 | unsigned int num_spacings; |
| 115 | unsigned int spacings[RADIO_NUM_SPACINGS_MAX]; |
| 116 | union { |
| 117 | radio_hal_fm_band_config_t fm; |
| 118 | radio_hal_am_band_config_t am; |
| 119 | }; |
| 120 | } radio_hal_band_config_t; |
| 121 | |
| 122 | /* Used internally by the framework to represent a band for s specific region */ |
| 123 | typedef struct radio_band_config { |
| 124 | radio_region_t region; |
| 125 | radio_hal_band_config_t band; |
| 126 | } radio_band_config_t; |
| 127 | |
| 128 | |
| 129 | /* Exposes properties of a given hardware radio module. |
| 130 | * NOTE: current framework implementation supports only one audio source (num_audio_sources = 1). |
| 131 | * The source corresponds to AUDIO_DEVICE_IN_FM_TUNER. |
| 132 | * If more than one tuner is supported (num_tuners > 1), only one can be connected to the audio |
| 133 | * source. */ |
| 134 | typedef struct radio_hal_properties { |
| 135 | radio_class_t class_id; /* Class of this module. E.g RADIO_CLASS_AM_FM */ |
| 136 | char implementor[RADIO_STRING_LEN_MAX]; /* implementor name */ |
| 137 | char product[RADIO_STRING_LEN_MAX]; /* product name */ |
| 138 | char version[RADIO_STRING_LEN_MAX]; /* product version */ |
| 139 | char serial[RADIO_STRING_LEN_MAX]; /* serial number (for subscription services) */ |
| 140 | unsigned int num_tuners; /* number of tuners controllable independently */ |
| 141 | unsigned int num_audio_sources; /* number of audio sources driven simultaneously */ |
| 142 | bool supports_capture; /* the hardware supports capture of audio source audio HAL */ |
| 143 | unsigned int num_bands; /* number of band descriptors */ |
| 144 | radio_hal_band_config_t bands[RADIO_NUM_BANDS_MAX]; /* band descriptors */ |
| 145 | } radio_hal_properties_t; |
| 146 | |
| 147 | /* Used internally by the framework. Same information as in struct radio_hal_properties plus a |
| 148 | * unique handle and one band configuration per region. */ |
| 149 | typedef struct radio_properties { |
| 150 | radio_handle_t handle; |
| 151 | radio_class_t class_id; |
| 152 | char implementor[RADIO_STRING_LEN_MAX]; |
| 153 | char product[RADIO_STRING_LEN_MAX]; |
| 154 | char version[RADIO_STRING_LEN_MAX]; |
| 155 | char serial[RADIO_STRING_LEN_MAX]; |
| 156 | unsigned int num_tuners; |
| 157 | unsigned int num_audio_sources; |
| 158 | bool supports_capture; |
| 159 | unsigned int num_bands; |
| 160 | radio_band_config_t bands[RADIO_NUM_BANDS_MAX]; |
| 161 | } radio_properties_t; |
| 162 | |
| 163 | /* Radio program information. Returned by the HAL with event RADIO_EVENT_TUNED. |
| 164 | * Contains information on currently tuned channel. |
| 165 | */ |
| 166 | typedef struct radio_program_info { |
| 167 | unsigned int channel; /* current channel. (e.g kHz for band type RADIO_BAND_FM) */ |
| 168 | unsigned int sub_channel; /* current sub channel. (used for RADIO_BAND_FM_HD) */ |
| 169 | bool tuned; /* tuned to a program or not */ |
| 170 | bool stereo; /* program is stereo or not */ |
| 171 | bool digital; /* digital program or not (e.g HD Radio program) */ |
| 172 | unsigned int signal_strength; /* signal strength from 0 to 100 */ |
| 173 | radio_metadata_t *metadata; /* non null if meta data are present (e.g PTY, song title ...) */ |
| 174 | } radio_program_info_t; |
| 175 | |
| 176 | |
| 177 | /* Events sent to the framework via the HAL callback. An event can notify the completion of an |
| 178 | * asynchronous command (configuration, tune, scan ...) or a spontaneous change (antenna connection, |
| 179 | * failure, AF switching, meta data reception... */ |
| 180 | enum { |
| 181 | RADIO_EVENT_HW_FAILURE = 0, /* hardware module failure. Requires reopening the tuner */ |
| 182 | RADIO_EVENT_CONFIG = 1, /* configuration change completed */ |
| 183 | RADIO_EVENT_ANTENNA = 2, /* Antenna connected, disconnected */ |
| 184 | RADIO_EVENT_TUNED = 3, /* tune, step, scan completed */ |
| 185 | RADIO_EVENT_METADATA = 4, /* New meta data received */ |
| 186 | RADIO_EVENT_TA = 5, /* Traffic announcement start or stop */ |
| 187 | RADIO_EVENT_AF_SWITCH = 6, /* Switch to Alternate Frequency */ |
Sanket Agarwal | 2ccc52c | 2015-10-16 14:37:01 -0700 | [diff] [blame] | 188 | RADIO_EVENT_EA = 7, /* Emergency announcement start or stop */ |
Eric Laurent | 699ce29 | 2015-02-10 18:30:42 -0800 | [diff] [blame] | 189 | // begin framework only events |
| 190 | RADIO_EVENT_CONTROL = 100, /* loss/gain of tuner control */ |
| 191 | RADIO_EVENT_SERVER_DIED = 101, /* radio service died */ |
| 192 | }; |
| 193 | typedef unsigned int radio_event_type_t; |
| 194 | |
| 195 | /* Event passed to the framework by the HAL callback */ |
| 196 | typedef struct radio_hal_event { |
| 197 | radio_event_type_t type; /* event type */ |
| 198 | int status; /* used by RADIO_EVENT_CONFIG, RADIO_EVENT_TUNED */ |
| 199 | union { |
Sanket Agarwal | 2ccc52c | 2015-10-16 14:37:01 -0700 | [diff] [blame] | 200 | /* RADIO_EVENT_ANTENNA, RADIO_EVENT_TA, RADIO_EVENT_EA */ |
| 201 | bool on; |
Eric Laurent | 699ce29 | 2015-02-10 18:30:42 -0800 | [diff] [blame] | 202 | radio_hal_band_config_t config; /* RADIO_EVENT_CONFIG */ |
| 203 | radio_program_info_t info; /* RADIO_EVENT_TUNED, RADIO_EVENT_AF_SWITCH */ |
| 204 | radio_metadata_t *metadata; /* RADIO_EVENT_METADATA */ |
| 205 | }; |
| 206 | } radio_hal_event_t; |
| 207 | |
| 208 | /* Used internally by the framework. Same information as in struct radio_hal_event */ |
| 209 | typedef struct radio_event { |
| 210 | radio_event_type_t type; |
| 211 | int status; |
| 212 | union { |
| 213 | bool on; |
| 214 | radio_band_config_t config; |
| 215 | radio_program_info_t info; |
| 216 | radio_metadata_t *metadata; /* offset from start of struct when in shared memory */ |
| 217 | }; |
| 218 | } radio_event_t; |
| 219 | |
| 220 | |
| 221 | static radio_rds_t radio_rds_for_region(bool rds, radio_region_t region) { |
| 222 | if (!rds) |
| 223 | return RADIO_RDS_NONE; |
| 224 | switch(region) { |
| 225 | case RADIO_REGION_ITU_1: |
| 226 | case RADIO_REGION_OIRT: |
| 227 | case RADIO_REGION_JAPAN: |
| 228 | case RADIO_REGION_KOREA: |
| 229 | return RADIO_RDS_WORLD; |
| 230 | case RADIO_REGION_ITU_2: |
| 231 | return RADIO_RDS_US; |
| 232 | default: |
| 233 | return RADIO_REGION_NONE; |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | static radio_deemphasis_t radio_demephasis_for_region(radio_region_t region) { |
| 238 | switch(region) { |
| 239 | case RADIO_REGION_KOREA: |
| 240 | case RADIO_REGION_ITU_2: |
| 241 | return RADIO_DEEMPHASIS_75; |
| 242 | case RADIO_REGION_ITU_1: |
| 243 | case RADIO_REGION_OIRT: |
| 244 | case RADIO_REGION_JAPAN: |
| 245 | default: |
| 246 | return RADIO_DEEMPHASIS_50; |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | #endif // ANDROID_RADIO_H |