1213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk/*
2213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * Copyright (C) 2017 The Android Open Source Project
3213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk *
4213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * Licensed under the Apache License, Version 2.0 (the "License");
5213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * you may not use this file except in compliance with the License.
6213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * You may obtain a copy of the License at
7213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk *
8213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk *      http://www.apache.org/licenses/LICENSE-2.0
9213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk *
10213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * Unless required by applicable law or agreed to in writing, software
11213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * distributed under the License is distributed on an "AS IS" BASIS,
12213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * See the License for the specific language governing permissions and
14213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * limitations under the License.
15213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk */
16213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#define LOG_TAG "BroadcastRadio"
17213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk//#define LOG_NDEBUG 0
18213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
19213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include <log/log.h>
20213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
21213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include "BroadcastRadio.h"
22213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include "Tuner.h"
23213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include "Utils.h"
24213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
25213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace android {
26213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace hardware {
27213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace broadcastradio {
28213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace V1_1 {
29213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace implementation {
30213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
31213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykusing ::android::sp;
32213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
33213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykBroadcastRadio::BroadcastRadio(Class classId)
34213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        : mStatus(Result::NOT_INITIALIZED), mClassId(classId), mHwDevice(NULL)
35213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{
36213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}
37213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
38213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykBroadcastRadio::~BroadcastRadio()
39213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{
40213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (mHwDevice != NULL) {
41213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        radio_hw_device_close(mHwDevice);
42213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
43213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}
44213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
45213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykvoid BroadcastRadio::onFirstRef()
46213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{
47213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    const hw_module_t *mod;
48213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    int rc;
49213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    ALOGI("%s mClassId %d", __FUNCTION__, mClassId);
50213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
51213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    mHwDevice = NULL;
52213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    const char *classString = Utils::getClassString(mClassId);
53213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (classString == NULL) {
54213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        ALOGE("invalid class ID %d", mClassId);
55213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        mStatus = Result::INVALID_ARGUMENTS;
56213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        return;
57213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
58213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
59213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    ALOGI("%s RADIO_HARDWARE_MODULE_ID %s %s",
60213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk            __FUNCTION__, RADIO_HARDWARE_MODULE_ID, classString);
61213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
62213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    rc = hw_get_module_by_class(RADIO_HARDWARE_MODULE_ID, classString, &mod);
63213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (rc != 0) {
64213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        ALOGE("couldn't load radio module %s.%s (%s)",
65213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk                RADIO_HARDWARE_MODULE_ID, classString, strerror(-rc));
66213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        return;
67213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
68213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    rc = radio_hw_device_open(mod, &mHwDevice);
69213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (rc != 0) {
70213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        ALOGE("couldn't open radio hw device in %s.%s (%s)",
71213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk                RADIO_HARDWARE_MODULE_ID, "primary", strerror(-rc));
72213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        mHwDevice = NULL;
73213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        return;
74213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
75213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (mHwDevice->common.version != RADIO_DEVICE_API_VERSION_CURRENT) {
76213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        ALOGE("wrong radio hw device version %04x", mHwDevice->common.version);
77213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        radio_hw_device_close(mHwDevice);
78213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        mHwDevice = NULL;
79213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    } else {
80213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        mStatus = Result::OK;
81213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
82213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}
83213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
84213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykint BroadcastRadio::closeHalTuner(const struct radio_tuner *halTuner)
85213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{
86213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    ALOGV("%s", __FUNCTION__);
87213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (mHwDevice == NULL) {
88213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        return -ENODEV;
89213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
90213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (halTuner == 0) {
91213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        return -EINVAL;
92213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
93213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    return mHwDevice->close_tuner(mHwDevice, halTuner);
94213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}
95213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
96213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
97803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk// Methods from ::android::hardware::broadcastradio::V1_1::IBroadcastRadio follow.
98213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykReturn<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb)
99213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{
100213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    int rc;
101213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    radio_hal_properties_t halProperties;
102213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    Properties properties;
103213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
104213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (mHwDevice == NULL) {
105213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        rc = -ENODEV;
106213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        goto exit;
107213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
108213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    rc = mHwDevice->get_properties(mHwDevice, &halProperties);
109213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (rc == 0) {
110213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        Utils::convertPropertiesFromHal(&properties, &halProperties);
111213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
112213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
113213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykexit:
114213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    _hidl_cb(Utils::convertHalResult(rc), properties);
115213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    return Void();
116213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}
117213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
118803301a2ed397ee39c9e703c611703053aad594fTomasz WasilczykReturn<void> BroadcastRadio::getProperties_1_1(getProperties_1_1_cb _hidl_cb __unused)
119803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk{
120803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
121803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk}
122803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk
123213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykReturn<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio,
124213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    const sp<V1_0::ITunerCallback>& callback, openTuner_cb _hidl_cb)
125213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{
126213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    sp<Tuner> tunerImpl = new Tuner(callback, this);
127213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
128213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    radio_hal_band_config_t halConfig;
129213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    const struct radio_tuner *halTuner;
130213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    Utils::convertBandConfigToHal(&halConfig, &config);
131213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    int rc = mHwDevice->open_tuner(mHwDevice, &halConfig, audio, Tuner::callback,
132213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk            tunerImpl.get(), &halTuner);
133213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    if (rc == 0) {
134213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk        tunerImpl->setHalTuner(halTuner);
135213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    }
136213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
137213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    _hidl_cb(Utils::convertHalResult(rc), tunerImpl);
138213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk    return Void();
139213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}
140213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk
141213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} // namespace implementation
142213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}  // namespace V1_1
143213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}  // namespace broadcastradio
144213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}  // namespace hardware
145213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk}  // namespace android
146