As you note, there are two modern patterns for spelling //oː// in kana:
[CONSONANT or VOWEL KANA ending in //o//] + お, or + う.
For the volitional ending in う
This was originally the volitional auxiliary / suffix む, which attached to the irrealis or 未然形【みぜんけい】 ("hasn't happened yet") form.
- For 四段活用【よだんかつよう】 verbs, the irrealis ends in //a//, so the volitional ending was effectively //-amu//. The む ending was somewhat unstable, and it shifted to just vowel う, resulting in //-au//. This then shifted phonetically to //ɔː// (kind of like English "awww"), which we still find in the 1603 Nippo Jisho ("Japanese-Portuguese Dictionary", available online here) as a distinct sound from //oː//. Between then and now, //ɔː// merged with //oː//, resulting in the modern 五段活用【ごだんかつよう】 (the fifth being this //oː// ending).
- For 上【かみ】 and 下一段【しもいちだん】 verbs, the irrealis stem is the same as the other stems -- ending in //i// for 上【かみ】 and in //e// for 下【しも】, so the volitional ending was effectively either //-imu// or //-emu//. Due to that same instability in む, this became //-iu// or //-eu//. Due to further phonetic shifts, this became first a glide //-joː//, such as 見む (//mimu//) → 見ょう (//mjoː//) and 食べむ (//tabemu//) → 食びょう (//tabjoː//), and then the //joː// ending was re-analyzed as a suffix, and the subsumed-and-contracted vowel of the stem re-appeared, as in 見よう (//mijoː//) and 食べよう (//tabejoː//).
For Chinese-derived long-//o// vowels in kanji readings
These are sometimes the result of an earlier manifestation of this same "//a// + nasal" sound shift, generally occurring at the time of borrowing. 王 is one example, realized in Middle Chinese as something like //huaŋ//. Japanese speakers may have heard this more as //waŋ//, but earlier Japanese didn't have any ん sound -- so the Chinese term was imported into the Japanese sound system as //wau//, with the earlier hiragana representation of わう. Due to the //-au// → //-ɔː// → //-oː// sound shift described above, this became //wɔː// and then //oː// (since //wo// doesn't really exist as a phonemic sound in Japanese).
Alternatively, they may have been //-ip// or //-ep// in Middle Chinese. That final //-p// became //-pu// in Japanese, and then as //p// shifted to //f//, final //-fu// softened further to //-u//, and then we see the same //-iu// or //-eu// to //-joː// shift as above. 協 is one example, realized in Middle Chinese as //gep//, giving rise to the 呉音【ごおん】 reading of ぎょう.
For native-derived long-//o// vowels
Some of these arose from the same //-iu// or //-eu// shift as above. One such example is 今日【きょう】, reconstructed as //kepu// in the earliest form. These are spelled with the う as the vowel lengthener.
Others arose from a related shift, where the mid-word ひ or び of 人 would shift to ふ or ぶ, and then result in an ending of either //-uto// or //-udo//. Examples include 素人【しろうと】 (from しろ + ひと) and 仲人【なこうど】 (from なか + びと). These are also spelled with the う as the vowel lengthener.
Still others of these arose from the lenition (softening) of a consonant, such as 遠【とお】 from earlier //topo//, or 頰【ほお】 from earlier //popo//. These are spelled with the お as the vowel lengthener.
There are other patterns that also occurred, as in お父【とう】さん. An earlier form of 父 was //toto//, and the honorific form during the Edo period was //otossan//, from a contraction of the second //-to// with the //s// in suffix //-san//. During the Meiji period, this //otossan// was reworked by the Ministry of Education into //otoːsan//, which was spread via textbooks as the new standard form for this word.
If you dig around in a monolingual Japanese dictionary, you'll find that the entry often starts with a hiragana spelling that differs from the expected modern spelling. See the 大きい entry at Weblio, for instance, which starts with:
おおき・い おほきい ［3］ 【大きい】
That second kana string is the old, pre-reform kana spelling, and those old spellings give you some clue as to how the term was pronounced in earlier stages of the language. These can, in turn, help explain the derivation of the long-vowel readings.